@@ -19,46 +19,14 @@ import * as validator from './validator';
19
19
import * as jwt from 'jsonwebtoken' ;
20
20
import { HttpClient , HttpRequestConfig , HttpError } from './api-request' ;
21
21
import { FirebaseApp } from '../firebase-app' ;
22
- import { ErrorInfo , PrefixedFirebaseError ,
23
- BaseClientErrorCode , AuthClientErrorCode , FirebaseAuthError } from './error' ;
22
+ import { ErrorCodeConfig , ErrorInfo , PrefixedFirebaseError } from './error' ;
24
23
import { auth } from '../auth/index' ;
25
24
26
25
import DecodedIdToken = auth . DecodedIdToken ;
27
26
28
27
// Audience to use for Firebase Auth Custom tokens
29
28
const FIREBASE_AUDIENCE = 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit' ;
30
29
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
-
62
30
/** Interface that defines token related user facing information. */
63
31
export interface FirebaseTokenInfo {
64
32
/** Documentation URL. */
@@ -71,9 +39,9 @@ export interface FirebaseTokenInfo {
71
39
shortName : string ;
72
40
/** JWT Expiration error code. */
73
41
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. */
77
45
errorType : new ( info : ErrorInfo , message ?: string ) => PrefixedFirebaseError ;
78
46
}
79
47
@@ -90,48 +58,49 @@ export class FirebaseTokenVerifier {
90
58
private readonly app : FirebaseApp ) {
91
59
92
60
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 ,
94
63
'The provided public client certificate URL is an invalid URL.' ,
95
64
) ;
96
65
97
66
} else if ( ! validator . isNonEmptyString ( algorithm ) ) {
98
67
throw new this . tokenInfo . errorType (
99
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
68
+ this . tokenInfo . errorCodeConfig . invalidArg ,
100
69
'The provided JWT algorithm is an empty string.' ,
101
70
) ;
102
71
} else if ( ! validator . isURL ( issuer ) ) {
103
72
throw new this . tokenInfo . errorType (
104
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
73
+ this . tokenInfo . errorCodeConfig . invalidArg ,
105
74
'The provided JWT issuer is an invalid URL.' ,
106
75
) ;
107
76
} else if ( ! validator . isNonNullObject ( tokenInfo ) ) {
108
77
throw new this . tokenInfo . errorType (
109
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
78
+ this . tokenInfo . errorCodeConfig . invalidArg ,
110
79
'The provided JWT information is not an object or null.' ,
111
80
) ;
112
81
} else if ( ! validator . isURL ( tokenInfo . url ) ) {
113
82
throw new this . tokenInfo . errorType (
114
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
83
+ this . tokenInfo . errorCodeConfig . invalidArg ,
115
84
'The provided JWT verification documentation URL is invalid.' ,
116
85
) ;
117
86
} else if ( ! validator . isNonEmptyString ( tokenInfo . verifyApiName ) ) {
118
87
throw new this . tokenInfo . errorType (
119
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
88
+ this . tokenInfo . errorCodeConfig . invalidArg ,
120
89
'The JWT verify API name must be a non-empty string.' ,
121
90
) ;
122
91
} else if ( ! validator . isNonEmptyString ( tokenInfo . jwtName ) ) {
123
92
throw new this . tokenInfo . errorType (
124
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
93
+ this . tokenInfo . errorCodeConfig . invalidArg ,
125
94
'The JWT public full name must be a non-empty string.' ,
126
95
) ;
127
96
} else if ( ! validator . isNonEmptyString ( tokenInfo . shortName ) ) {
128
97
throw new this . tokenInfo . errorType (
129
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
98
+ this . tokenInfo . errorCodeConfig . invalidArg ,
130
99
'The JWT public short name must be a non-empty string.' ,
131
100
) ;
132
101
} else if ( ! validator . isNonNullObject ( tokenInfo . expiredErrorCode ) || ! ( 'code' in tokenInfo . expiredErrorCode ) ) {
133
102
throw new this . tokenInfo . errorType (
134
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
103
+ this . tokenInfo . errorCodeConfig . invalidArg ,
135
104
'The JWT expiration error code must be a non-null ErrorInfo object.' ,
136
105
) ;
137
106
}
@@ -151,7 +120,7 @@ export class FirebaseTokenVerifier {
151
120
public verifyJWT ( jwtToken : string , isEmulator = false ) : Promise < DecodedIdToken > {
152
121
if ( ! validator . isString ( jwtToken ) ) {
153
122
throw new this . tokenInfo . errorType (
154
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
123
+ this . tokenInfo . errorCodeConfig . invalidArg ,
155
124
`First argument to ${ this . tokenInfo . verifyApiName } must be a ${ this . tokenInfo . jwtName } string.` ,
156
125
) ;
157
126
}
@@ -169,7 +138,7 @@ export class FirebaseTokenVerifier {
169
138
) : Promise < DecodedIdToken > {
170
139
if ( ! validator . isNonEmptyString ( projectId ) ) {
171
140
throw new this . tokenInfo . errorType (
172
- this . tokenInfo . errorCodeType . INVALID_CREDENTIAL ,
141
+ this . tokenInfo . errorCodeConfig . invalidCredential ,
173
142
'Must initialize app with a cert credential or set your Firebase project ID as the ' +
174
143
`GOOGLE_CLOUD_PROJECT environment variable to call ${ this . tokenInfo . verifyApiName } .` ,
175
144
) ;
@@ -226,7 +195,7 @@ export class FirebaseTokenVerifier {
226
195
verifyJwtTokenDocsMessage ;
227
196
}
228
197
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 ) ) ;
230
199
}
231
200
232
201
if ( isEmulator ) {
@@ -238,7 +207,7 @@ export class FirebaseTokenVerifier {
238
207
if ( ! Object . prototype . hasOwnProperty . call ( publicKeys , header . kid ) ) {
239
208
return Promise . reject (
240
209
new this . tokenInfo . errorType (
241
- this . tokenInfo . errorCodeType . INVALID_ARGUMENT ,
210
+ this . tokenInfo . errorCodeConfig . invalidArg ,
242
211
`${ this . tokenInfo . jwtName } has "kid" claim which does not correspond to a known public key. ` +
243
212
`Most likely the ${ this . tokenInfo . shortName } is expired, so get a fresh token from your ` +
244
213
'client app and try again.' ,
@@ -276,9 +245,9 @@ export class FirebaseTokenVerifier {
276
245
return reject ( new this . tokenInfo . errorType ( this . tokenInfo . expiredErrorCode , errorMessage ) ) ;
277
246
} else if ( error . name === 'JsonWebTokenError' ) {
278
247
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 ) ) ;
280
249
}
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 ) ) ;
282
251
} else {
283
252
const decodedIdToken = ( decodedToken as DecodedIdToken ) ;
284
253
decodedIdToken . uid = decodedIdToken . sub ;
@@ -338,41 +307,9 @@ export class FirebaseTokenVerifier {
338
307
} else {
339
308
errorMessage += `${ resp . text } ` ;
340
309
}
341
- throw new this . tokenInfo . errorType ( this . tokenInfo . errorCodeType . INTERNAL_ERROR , errorMessage ) ;
310
+ throw new this . tokenInfo . errorType ( this . tokenInfo . errorCodeConfig . internalError , errorMessage ) ;
342
311
}
343
312
throw err ;
344
313
} ) ;
345
314
}
346
315
}
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