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