@@ -37,7 +37,7 @@ import {
37
37
} from './client' ;
38
38
import { writeTokenToStorage , readTokenFromStorage } from './storage' ;
39
39
import { getDebugToken , isDebugMode } from './debug' ;
40
- import { base64 } from '@firebase/util' ;
40
+ import { base64 , issuedAtTime } from '@firebase/util' ;
41
41
import { ERROR_FACTORY , AppCheckError } from './errors' ;
42
42
import { logger } from './logger' ;
43
43
@@ -113,7 +113,19 @@ export async function getToken(
113
113
try {
114
114
if ( state . customProvider ) {
115
115
const customToken = await state . customProvider . getToken ( ) ;
116
- token = { ...customToken , issuedAtTimeMillis : Date . now ( ) } ;
116
+ // Try to extract IAT from custom token, in case this token is not
117
+ // being newly issued. JWT timestamps are in seconds since epoch.
118
+ const issuedAtTimeSeconds = issuedAtTime ( customToken . token ) ;
119
+ // Very basic validation, use current timestamp as IAT if JWT
120
+ // has no `iat` field or value is out of bounds.
121
+ const issuedAtTimeMillis =
122
+ issuedAtTimeSeconds !== null &&
123
+ issuedAtTimeSeconds < Date . now ( ) &&
124
+ issuedAtTimeSeconds > 0
125
+ ? issuedAtTimeSeconds * 1000
126
+ : Date . now ( ) ;
127
+
128
+ token = { ...customToken , issuedAtTimeMillis } ;
117
129
} else {
118
130
const attestedClaimsToken = await getReCAPTCHAToken ( app ) . catch ( _e => {
119
131
// reCaptcha.execute() throws null which is not very descriptive.
0 commit comments