@@ -19,46 +19,14 @@ import * as validator from './validator';
1919import * as jwt from 'jsonwebtoken' ;
2020import { HttpClient , HttpRequestConfig , HttpError } from './api-request' ;
2121import { FirebaseApp } from '../firebase-app' ;
22- import { ErrorInfo , PrefixedFirebaseError ,
23- BaseClientErrorCode , AuthClientErrorCode , FirebaseAuthError } from './error' ;
22+ import { ErrorCodeConfig , ErrorInfo , PrefixedFirebaseError } from './error' ;
2423import { auth } from '../auth/index' ;
2524
2625import DecodedIdToken = auth . DecodedIdToken ;
2726
2827// Audience to use for Firebase Auth Custom tokens
2928const FIREBASE_AUDIENCE = 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit' ;
3029
31- export const ALGORITHM_RS256 = 'RS256' ;
32-
33- // URL containing the public keys for the Google certs (whose private keys are used to sign Firebase
34- // Auth ID tokens)
35- const CLIENT_CERT_URL = 'https://www.googleapis.com/robot/v1/metadata/x509/[email protected] ' ; 36-
37- // URL containing the public keys for Firebase session cookies. This will be updated to a different URL soon.
38- const SESSION_COOKIE_CERT_URL = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys' ;
39-
40- /** User facing token information related to the Firebase ID token. */
41- export const ID_TOKEN_INFO : FirebaseTokenInfo = {
42- url : 'https://firebase.google.com/docs/auth/admin/verify-id-tokens' ,
43- verifyApiName : 'verifyIdToken()' ,
44- jwtName : 'Firebase ID token' ,
45- shortName : 'ID token' ,
46- expiredErrorCode : AuthClientErrorCode . ID_TOKEN_EXPIRED ,
47- errorCodeType : AuthClientErrorCode ,
48- errorType : FirebaseAuthError ,
49- } ;
50-
51- /** User facing token information related to the Firebase session cookie. */
52- export const SESSION_COOKIE_INFO : FirebaseTokenInfo = {
53- url : 'https://firebase.google.com/docs/auth/admin/manage-cookies' ,
54- verifyApiName : 'verifySessionCookie()' ,
55- jwtName : 'Firebase session cookie' ,
56- shortName : 'session cookie' ,
57- expiredErrorCode : AuthClientErrorCode . SESSION_COOKIE_EXPIRED ,
58- errorCodeType : AuthClientErrorCode ,
59- errorType : FirebaseAuthError ,
60- } ;
61-
6230/** Interface that defines token related user facing information. */
6331export interface FirebaseTokenInfo {
6432 /** Documentation URL. */
@@ -71,9 +39,9 @@ export interface FirebaseTokenInfo {
7139 shortName : string ;
7240 /** JWT Expiration error code. */
7341 expiredErrorCode : ErrorInfo ;
74- /** Generic error code type. */
75- errorCodeType : typeof BaseClientErrorCode ;
76- /** Error type. */
42+ /** Error code config of the public error type. */
43+ errorCodeConfig : ErrorCodeConfig ;
44+ /** Public error type. */
7745 errorType : new ( info : ErrorInfo , message ?: string ) => PrefixedFirebaseError ;
7846}
7947
@@ -90,48 +58,49 @@ export class FirebaseTokenVerifier {
9058 private readonly app : FirebaseApp ) {
9159
9260 if ( ! validator . isURL ( clientCertUrl ) ) {
93- throw new this . tokenInfo . errorType ( this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
61+ throw new this . tokenInfo . errorType (
62+ this . tokenInfo . errorCodeConfig . invalidArg ,
9463 'The provided public client certificate URL is an invalid URL.' ,
9564 ) ;
9665
9766 } else if ( ! validator . isNonEmptyString ( algorithm ) ) {
9867 throw new this . tokenInfo . errorType (
99- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
68+ this . tokenInfo . errorCodeConfig . invalidArg ,
10069 'The provided JWT algorithm is an empty string.' ,
10170 ) ;
10271 } else if ( ! validator . isURL ( issuer ) ) {
10372 throw new this . tokenInfo . errorType (
104- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
73+ this . tokenInfo . errorCodeConfig . invalidArg ,
10574 'The provided JWT issuer is an invalid URL.' ,
10675 ) ;
10776 } else if ( ! validator . isNonNullObject ( tokenInfo ) ) {
10877 throw new this . tokenInfo . errorType (
109- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
78+ this . tokenInfo . errorCodeConfig . invalidArg ,
11079 'The provided JWT information is not an object or null.' ,
11180 ) ;
11281 } else if ( ! validator . isURL ( tokenInfo . url ) ) {
11382 throw new this . tokenInfo . errorType (
114- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
83+ this . tokenInfo . errorCodeConfig . invalidArg ,
11584 'The provided JWT verification documentation URL is invalid.' ,
11685 ) ;
11786 } else if ( ! validator . isNonEmptyString ( tokenInfo . verifyApiName ) ) {
11887 throw new this . tokenInfo . errorType (
119- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
88+ this . tokenInfo . errorCodeConfig . invalidArg ,
12089 'The JWT verify API name must be a non-empty string.' ,
12190 ) ;
12291 } else if ( ! validator . isNonEmptyString ( tokenInfo . jwtName ) ) {
12392 throw new this . tokenInfo . errorType (
124- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
93+ this . tokenInfo . errorCodeConfig . invalidArg ,
12594 'The JWT public full name must be a non-empty string.' ,
12695 ) ;
12796 } else if ( ! validator . isNonEmptyString ( tokenInfo . shortName ) ) {
12897 throw new this . tokenInfo . errorType (
129- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
98+ this . tokenInfo . errorCodeConfig . invalidArg ,
13099 'The JWT public short name must be a non-empty string.' ,
131100 ) ;
132101 } else if ( ! validator . isNonNullObject ( tokenInfo . expiredErrorCode ) || ! ( 'code' in tokenInfo . expiredErrorCode ) ) {
133102 throw new this . tokenInfo . errorType (
134- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
103+ this . tokenInfo . errorCodeConfig . invalidArg ,
135104 'The JWT expiration error code must be a non-null ErrorInfo object.' ,
136105 ) ;
137106 }
@@ -151,7 +120,7 @@ export class FirebaseTokenVerifier {
151120 public verifyJWT ( jwtToken : string , isEmulator = false ) : Promise < DecodedIdToken > {
152121 if ( ! validator . isString ( jwtToken ) ) {
153122 throw new this . tokenInfo . errorType (
154- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
123+ this . tokenInfo . errorCodeConfig . invalidArg ,
155124 `First argument to ${ this . tokenInfo . verifyApiName } must be a ${ this . tokenInfo . jwtName } string.` ,
156125 ) ;
157126 }
@@ -169,7 +138,7 @@ export class FirebaseTokenVerifier {
169138 ) : Promise < DecodedIdToken > {
170139 if ( ! validator . isNonEmptyString ( projectId ) ) {
171140 throw new this . tokenInfo . errorType (
172- this . tokenInfo . errorCodeType . INVALID_CREDENTIAL ,
141+ this . tokenInfo . errorCodeConfig . invalidCredential ,
173142 'Must initialize app with a cert credential or set your Firebase project ID as the ' +
174143 `GOOGLE_CLOUD_PROJECT environment variable to call ${ this . tokenInfo . verifyApiName } .` ,
175144 ) ;
@@ -226,7 +195,7 @@ export class FirebaseTokenVerifier {
226195 verifyJwtTokenDocsMessage ;
227196 }
228197 if ( errorMessage ) {
229- return Promise . reject ( new this . tokenInfo . errorType ( this . tokenInfo . errorCodeType . INVALID_ARGUMENT , errorMessage ) ) ;
198+ return Promise . reject ( new this . tokenInfo . errorType ( this . tokenInfo . errorCodeConfig . invalidArg , errorMessage ) ) ;
230199 }
231200
232201 if ( isEmulator ) {
@@ -238,7 +207,7 @@ export class FirebaseTokenVerifier {
238207 if ( ! Object . prototype . hasOwnProperty . call ( publicKeys , header . kid ) ) {
239208 return Promise . reject (
240209 new this . tokenInfo . errorType (
241- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
210+ this . tokenInfo . errorCodeConfig . invalidArg ,
242211 `${ this . tokenInfo . jwtName } has "kid" claim which does not correspond to a known public key. ` +
243212 `Most likely the ${ this . tokenInfo . shortName } is expired, so get a fresh token from your ` +
244213 'client app and try again.' ,
@@ -276,9 +245,9 @@ export class FirebaseTokenVerifier {
276245 return reject ( new this . tokenInfo . errorType ( this . tokenInfo . expiredErrorCode , errorMessage ) ) ;
277246 } else if ( error . name === 'JsonWebTokenError' ) {
278247 const errorMessage = `${ this . tokenInfo . jwtName } has invalid signature.` + verifyJwtTokenDocsMessage ;
279- return reject ( new this . tokenInfo . errorType ( this . tokenInfo . errorCodeType . INVALID_ARGUMENT , errorMessage ) ) ;
248+ return reject ( new this . tokenInfo . errorType ( this . tokenInfo . errorCodeConfig . invalidArg , errorMessage ) ) ;
280249 }
281- return reject ( new this . tokenInfo . errorType ( this . tokenInfo . errorCodeType . INVALID_ARGUMENT , error . message ) ) ;
250+ return reject ( new this . tokenInfo . errorType ( this . tokenInfo . errorCodeConfig . invalidArg , error . message ) ) ;
282251 } else {
283252 const decodedIdToken = ( decodedToken as DecodedIdToken ) ;
284253 decodedIdToken . uid = decodedIdToken . sub ;
@@ -338,41 +307,9 @@ export class FirebaseTokenVerifier {
338307 } else {
339308 errorMessage += `${ resp . text } ` ;
340309 }
341- throw new this . tokenInfo . errorType ( this . tokenInfo . errorCodeType . INTERNAL_ERROR , errorMessage ) ;
310+ throw new this . tokenInfo . errorType ( this . tokenInfo . errorCodeConfig . internalError , errorMessage ) ;
342311 }
343312 throw err ;
344313 } ) ;
345314 }
346315}
347-
348- /**
349- * Creates a new FirebaseTokenVerifier to verify Firebase ID tokens.
350- *
351- * @param {FirebaseApp } app Firebase app instance.
352- * @return {FirebaseTokenVerifier }
353- */
354- export function createIdTokenVerifier ( app : FirebaseApp ) : FirebaseTokenVerifier {
355- return new FirebaseTokenVerifier (
356- CLIENT_CERT_URL ,
357- ALGORITHM_RS256 ,
358- 'https://securetoken.google.com/' ,
359- ID_TOKEN_INFO ,
360- app
361- ) ;
362- }
363-
364- /**
365- * Creates a new FirebaseTokenVerifier to verify Firebase session cookies.
366- *
367- * @param {FirebaseApp } app Firebase app instance.
368- * @return {FirebaseTokenVerifier }
369- */
370- export function createSessionCookieVerifier ( app : FirebaseApp ) : FirebaseTokenVerifier {
371- return new FirebaseTokenVerifier (
372- SESSION_COOKIE_CERT_URL ,
373- ALGORITHM_RS256 ,
374- 'https://session.firebase.google.com/' ,
375- SESSION_COOKIE_INFO ,
376- app
377- ) ;
378- }
0 commit comments