Skip to content

Commit dc14f5c

Browse files
authored
Add the forceRefresh parameter to Installations' getToken method (#2239)
1 parent 9fcd221 commit dc14f5c

File tree

4 files changed

+38
-14
lines changed

4 files changed

+38
-14
lines changed

packages/installations/src/functions/get-token.test.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ import { sleep } from '../util/sleep';
3838
import { getToken } from './get-token';
3939

4040
const FID = 'dont-talk-to-strangers';
41-
const AUTH_TOKEN = 'authTokenFromServer';
41+
const AUTH_TOKEN = 'authToken';
42+
const NEW_AUTH_TOKEN = 'newAuthToken';
4243
const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
4344

4445
/**
@@ -104,7 +105,7 @@ const setupInstallationEntryMap: Map<
104105
const updatedEntry: RegisteredInstallationEntry = {
105106
...entry,
106107
authToken: {
107-
token: AUTH_TOKEN,
108+
token: NEW_AUTH_TOKEN,
108109
expiresIn: ONE_WEEK_MS,
109110
requestStatus: RequestStatus.COMPLETED,
110111
creationTime: Date.now()
@@ -196,7 +197,7 @@ describe('getToken', () => {
196197
registrationStatus: RequestStatus.COMPLETED,
197198
refreshToken: 'refreshToken',
198199
authToken: {
199-
token: AUTH_TOKEN,
200+
token: NEW_AUTH_TOKEN,
200201
expiresIn: ONE_WEEK_MS,
201202
requestStatus: RequestStatus.COMPLETED,
202203
creationTime: Date.now()
@@ -210,7 +211,7 @@ describe('getToken', () => {
210211
).callsFake(async () => {
211212
await sleep(100); // Request would take some time
212213
const result: CompletedAuthToken = {
213-
token: AUTH_TOKEN,
214+
token: NEW_AUTH_TOKEN,
214215
expiresIn: ONE_WEEK_MS,
215216
requestStatus: RequestStatus.COMPLETED,
216217
creationTime: Date.now()
@@ -226,7 +227,7 @@ describe('getToken', () => {
226227

227228
it('resolves with an auth token', async () => {
228229
const token = await getToken(app);
229-
expect(token).to.equal(AUTH_TOKEN);
230+
expect(token).to.be.oneOf([AUTH_TOKEN, NEW_AUTH_TOKEN]);
230231
});
231232

232233
it('saves the token in the DB', async () => {
@@ -382,16 +383,27 @@ describe('getToken', () => {
382383
expect(generateAuthTokenSpy).not.to.be.called;
383384
});
384385

386+
it('refreshes the token if forceRefresh is true', async () => {
387+
const token = await getToken(app, true);
388+
expect(token).to.equal(NEW_AUTH_TOKEN);
389+
expect(generateAuthTokenSpy).to.be.called;
390+
});
391+
385392
it('works even if the app is offline', async () => {
386393
stub(navigator, 'onLine').value(false);
387394

388395
const token = await getToken(app);
389396
expect(token).to.equal(AUTH_TOKEN);
390397
});
398+
399+
it('throws if the app is offline and forceRefresh is true', async () => {
400+
stub(navigator, 'onLine').value(false);
401+
402+
await expect(getToken(app, true)).to.be.rejected;
403+
});
391404
});
392405

393406
describe('when there is an auth token that is about to expire in the DB', () => {
394-
const DB_AUTH_TOKEN = 'authTokenFromDB';
395407
let clock: SinonFakeTimers;
396408

397409
beforeEach(async () => {
@@ -401,7 +413,7 @@ describe('getToken', () => {
401413
registrationStatus: RequestStatus.COMPLETED,
402414
refreshToken: 'refreshToken',
403415
authToken: {
404-
token: DB_AUTH_TOKEN,
416+
token: AUTH_TOKEN,
405417
expiresIn: ONE_WEEK_MS,
406418
requestStatus: RequestStatus.COMPLETED,
407419
creationTime:
@@ -414,13 +426,13 @@ describe('getToken', () => {
414426

415427
it('returns a different token after expiration', async () => {
416428
const token1 = await getToken(app);
417-
expect(token1).to.equal(DB_AUTH_TOKEN);
429+
expect(token1).to.equal(AUTH_TOKEN);
418430

419431
// Wait 30 minutes.
420432
clock.tick('30:00');
421433

422434
const token2 = await getToken(app);
423-
await expect(token2).to.equal(AUTH_TOKEN);
435+
await expect(token2).to.equal(NEW_AUTH_TOKEN);
424436
await expect(token2).not.to.equal(token1);
425437
});
426438
});
@@ -441,6 +453,12 @@ describe('getToken', () => {
441453
await set(appConfig, installationEntry);
442454
});
443455

456+
it('returns a different token', async () => {
457+
const token = await getToken(app);
458+
expect(token).to.equal(NEW_AUTH_TOKEN);
459+
expect(generateAuthTokenSpy).to.be.called;
460+
});
461+
444462
it('throws if the app is offline', async () => {
445463
stub(navigator, 'onLine').value(false);
446464

packages/installations/src/functions/get-token.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@ import { AppConfig } from '../interfaces/app-config';
2323
import { RequestStatus } from '../interfaces/installation-entry';
2424
import { ERROR_FACTORY, ErrorCode } from '../util/errors';
2525

26-
export async function getToken(app: FirebaseApp): Promise<string> {
26+
export async function getToken(
27+
app: FirebaseApp,
28+
forceRefresh = false
29+
): Promise<string> {
2730
const appConfig = extractAppConfig(app);
2831

2932
await completeInstallationRegistration(appConfig);
3033

3134
// At this point we either have a Registered Installation in the DB, or we've
3235
// already thrown an error.
33-
return refreshAuthToken(appConfig);
36+
return refreshAuthToken(appConfig, forceRefresh);
3437
}
3538

3639
async function completeInstallationRegistration(

packages/installations/src/helpers/refresh-auth-token.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ import { remove, set, update } from './idb-manager';
3636
*
3737
* Should only be called if the Firebase Installation is registered.
3838
*/
39-
export async function refreshAuthToken(appConfig: AppConfig): Promise<string> {
39+
export async function refreshAuthToken(
40+
appConfig: AppConfig,
41+
forceRefresh = false
42+
): Promise<string> {
4043
let tokenPromise: Promise<CompletedAuthToken> | undefined;
4144
const entry = await update(
4245
appConfig,
@@ -46,7 +49,7 @@ export async function refreshAuthToken(appConfig: AppConfig): Promise<string> {
4649
}
4750

4851
const oldAuthToken = oldEntry.authToken;
49-
if (isAuthTokenValid(oldAuthToken)) {
52+
if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {
5053
// There is a valid token in the DB.
5154
return oldEntry;
5255
} else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {

packages/installations/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function registerInstallations(instance: _FirebaseNamespace): void {
3535
return {
3636
app,
3737
getId: () => getId(app),
38-
getToken: () => getToken(app),
38+
getToken: (forceRefresh?: boolean) => getToken(app, forceRefresh),
3939
delete: () => deleteInstallation(app)
4040
};
4141
};

0 commit comments

Comments
 (0)