Skip to content

Commit f9f5e2a

Browse files
committed
Address PR comments
1 parent f63f8c5 commit f9f5e2a

File tree

5 files changed

+36
-13
lines changed

5 files changed

+36
-13
lines changed

packages/app-check/src/api.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ describe('api', () => {
380380
isTokenAutoRefreshEnabled: false
381381
});
382382

383-
expect(getState(app).tokenObservers.length).to.equal(1);
383+
expect(getState(app).tokenObservers.length).to.equal(0);
384384

385385
const fakeRecaptchaToken = 'fake-recaptcha-token';
386386
stub(reCAPTCHA, 'getToken').returns(Promise.resolve(fakeRecaptchaToken));
@@ -395,13 +395,13 @@ describe('api', () => {
395395

396396
await internalApi.getToken(appCheck as AppCheckService);
397397

398-
expect(getState(app).tokenObservers.length).to.equal(2);
398+
expect(getState(app).tokenObservers.length).to.equal(1);
399399

400400
expect(errorFn1).to.be.calledOnce;
401401
expect(errorFn1.args[0][0].name).to.include('exchange error');
402402

403403
unsubscribe1();
404-
expect(getState(app).tokenObservers.length).to.equal(1);
404+
expect(getState(app).tokenObservers.length).to.equal(0);
405405
});
406406
});
407407
});

packages/app-check/src/api.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,17 @@ export function initializeAppCheck(
9898

9999
const appCheck = provider.initialize({ options });
100100
_activate(app, options.provider, options.isTokenAutoRefreshEnabled);
101-
// Adding a listener will start the refresher and fetch a token if needed.
102-
// This gets a token ready and prevents a delay when an internal library
103-
// requests the token.
104-
// Listener function does not need to do anything, its base functionality
105-
// of calling getToken() already fetches token and writes it to memory/storage.
106-
addTokenListener(appCheck, ListenerType.INTERNAL, () => {});
101+
// If isTokenAutoRefreshEnabled is false, do not send any requests to the
102+
// exchange endpoint without an explicit call from the user either directly
103+
// or through another Firebase library (storage, functions, etc.)
104+
if (getState(app).isTokenAutoRefreshEnabled) {
105+
// Adding a listener will start the refresher and fetch a token if needed.
106+
// This gets a token ready and prevents a delay when an internal library
107+
// requests the token.
108+
// Listener function does not need to do anything, its base functionality
109+
// of calling getToken() already fetches token and writes it to memory/storage.
110+
addTokenListener(appCheck, ListenerType.INTERNAL, () => {});
111+
}
107112

108113
return appCheck;
109114
}

packages/app-check/src/internal-api.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,11 @@ describe('internal api', () => {
405405

406406
const token = await getToken(appCheck as AppCheckService);
407407

408+
// ReCaptchaV3Provider's _throttleData is private so checking
409+
// the resulting error message to be sure it has roughly the
410+
// correct throttle time. This also tests the time formatter.
411+
// Check both the error itself and that it makes it through to
412+
// console.warn
408413
expect(token.error?.message).to.include('503');
409414
expect(token.error?.message).to.include('00m');
410415
expect(warnStub.args[0][0]).to.include('503');
@@ -427,6 +432,12 @@ describe('internal api', () => {
427432

428433
const token = await getToken(appCheck as AppCheckService);
429434

435+
436+
// ReCaptchaV3Provider's _throttleData is private so checking
437+
// the resulting error message to be sure it has roughly the
438+
// correct throttle time. This also tests the time formatter.
439+
// Check both the error itself and that it makes it through to
440+
// console.warn
430441
expect(token.error?.message).to.include('403');
431442
expect(token.error?.message).to.include('1d');
432443
expect(warnStub.args[0][0]).to.include('403');
@@ -466,6 +477,8 @@ describe('internal api', () => {
466477
listener
467478
);
468479

480+
expect(getState(app).tokenRefresher?.isRunning()).to.be.undefined;
481+
469482
// addTokenListener() waits for the result of cachedTokenPromise
470483
// before starting the refresher
471484
await getState(app).cachedTokenPromise;

packages/app-check/src/providers.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,22 @@ describe('ReCaptchaV3Provider', () => {
8787
await expect(provider.getToken()).to.be.rejectedWith('503');
8888
expect(exchangeTokenStub).not.to.be.called;
8989
exchangeTokenStub.resetHistory();
90+
// Times below are max range of each random exponential wait,
91+
// the possible range is 2^(backoff_count) plus or minus 50%
9092
// Wait for 1.5 seconds to pass, should call exchange endpoint again
9193
// (and be rejected again)
9294
clock.tick(1500);
9395
await expect(provider.getToken()).to.be.rejectedWith('503');
9496
expect(exchangeTokenStub).to.be.called;
9597
exchangeTokenStub.resetHistory();
96-
// Wait for 10 seconds to pass, should call exchange endpoint again
98+
// Wait for 3 seconds to pass, should call exchange endpoint again
9799
// (and be rejected again)
98-
clock.tick(10000);
100+
clock.tick(3000);
99101
await expect(provider.getToken()).to.be.rejectedWith('503');
100102
expect(exchangeTokenStub).to.be.called;
101-
// Wait for 10 seconds to pass, should call exchange endpoint again
103+
// Wait for 6 seconds to pass, should call exchange endpoint again
102104
// (and succeed)
103-
clock.tick(10000);
105+
clock.tick(6000);
104106
exchangeTokenStub.restore();
105107
exchangeTokenStub = stub(client, 'exchangeToken').resolves({
106108
token: 'fake-exchange-token',

packages/app-check/src/providers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export class ReCaptchaV3Provider implements AppCheckProvider {
9393
Number((e as FirebaseError).customData?.httpStatus),
9494
this._throttleData
9595
);
96+
console.log('next interval', this._throttleData.allowRequestsAfter - Date.now());
9697
throw ERROR_FACTORY.create(AppCheckError.THROTTLED, {
9798
time: getDurationString(
9899
this._throttleData.allowRequestsAfter - Date.now()
@@ -247,6 +248,8 @@ export class CustomProvider implements AppCheckProvider {
247248
* Set throttle data to block requests until after a certain time
248249
* depending on the failed request's status code.
249250
* @param httpStatus - Status code of failed request.
251+
* @param throttleData - `ThrottleData` object containing previous throttle
252+
* data state.
250253
* @returns Data about current throttle state and expiration time.
251254
*/
252255
function setBackoff(

0 commit comments

Comments
 (0)