Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/app-check/.changeset/chatty-laws-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@firebase/app-check': patch
---

Prevent redundant exchangeToken calls in debug mode
22 changes: 22 additions & 0 deletions packages/app-check/src/internal-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,28 @@ describe('internal api', () => {
expect(token).to.deep.equal({ token: fakeRecaptchaAppCheckToken.token });
});

it('exchanges debug token only once if debug mode with no cached token', async () => {
const exchangeTokenStub: SinonStub = stub(
client,
'exchangeToken'
).returns(Promise.resolve(fakeRecaptchaAppCheckToken));
const debugState = getDebugState();
debugState.enabled = true;
debugState.token = new Deferred();
debugState.token.resolve('my-debug-token');
const appCheck = initializeAppCheck(app, {
provider: new ReCaptchaV3Provider(FAKE_SITE_KEY)
});
const appCheckServie = appCheck as AppCheckService;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: typo -appCheckServie

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @hsubox76 , I've updated the branch.

const [token1, token2] = await Promise.all([getToken(appCheckServie),getToken(appCheckServie)]);
expect(exchangeTokenStub.args[0][0].body['debug_token']).to.equal(
'my-debug-token'
);
expect(token1).to.deep.equal({ token: fakeRecaptchaAppCheckToken.token });
expect(token2).to.deep.equal({ token: fakeRecaptchaAppCheckToken.token });
expect(exchangeTokenStub).to.be.calledOnce;
});

it('throttles for a period less than 1d on 503', async () => {
// More detailed check of exponential backoff in providers.test.ts
const appCheck = initializeAppCheck(app, {
Expand Down
3 changes: 2 additions & 1 deletion packages/app-check/src/internal-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,11 @@ export async function getToken(
*/
if (isDebugMode()) {
try {
const debugToken = await getDebugToken();
// Avoid making another call to the exchange endpoint if one is in flight.
if (!state.exchangeTokenPromise) {
state.exchangeTokenPromise = exchangeToken(
getExchangeDebugTokenRequest(app, await getDebugToken()),
getExchangeDebugTokenRequest(app, debugToken),
appCheck.heartbeatServiceProvider
).finally(() => {
// Clear promise when settled - either resolved or rejected.
Expand Down
Loading