Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 27 additions & 0 deletions packages/auth/src/core/auth/auth_impl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ describe('core/auth/auth_impl', () => {
let exchangeTokenStub: sinon.SinonStub;
let mockToken: FirebaseToken;
let expiredMockToken: FirebaseToken;
let soonToExpireMockToken: FirebaseToken;
let tokenRefreshHandler: TokenRefreshHandler;
const tokenKey = `firebase:persistence-token:${FAKE_APP.options.apiKey!}:${
FAKE_APP.name
Expand All @@ -331,6 +332,10 @@ describe('core/auth/auth_impl', () => {
token: 'test-token',
expirationTime: Date.now() + 300000 // 5 minutes from now
};
soonToExpireMockToken = {
token: 'test-token',
expirationTime: Date.now() + 60000 // 1 minutes from now
};
expiredMockToken = {
token: 'expired-test-token',
expirationTime: Date.now() - 1000 // 1 second ago
Expand Down Expand Up @@ -364,6 +369,28 @@ describe('core/auth/auth_impl', () => {
expect(exchangeTokenStub).not.to.have.been.called;
});

it('should refresh the token if token is expiring in next 1 minute and a token refresh handler is set', async () => {
persistenceStub._get
.withArgs(tokenKey)
.resolves(soonToExpireMockToken as any);
auth.setTokenRefreshHandler(tokenRefreshHandler);

exchangeTokenStub.callsFake(async () => {
// When exchangeToken is called, simulate that the new token is persisted.
persistenceStub._get.withArgs(tokenKey).resolves(mockToken as any);
});

const token = await auth.getFirebaseAccessToken();

expect(tokenRefreshHandler.refreshIdpToken).to.have.been.calledOnce;
expect(exchangeTokenStub).to.have.been.calledWith(
auth,
'test-idp',
'new-id-token'
);
expect(token).to.eql('test-token');
});

it('should refresh the token if it is expired and a token refresh handler is set', async () => {
persistenceStub._get.withArgs(tokenKey).resolves(expiredMockToken as any);
auth.setTokenRefreshHandler(tokenRefreshHandler);
Expand Down
6 changes: 5 additions & 1 deletion packages/auth/src/core/auth/auth_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ export class AuthImpl implements AuthInternal, _FirebaseService {
private redirectUser: UserInternal | null = null;
private isProactiveRefreshEnabled = false;
private readonly EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION: number = 1;
private readonly TOKEN_EXPIRATION_BUFFER = 30_000;
// 1 minute buffer for expiry
// Intended for tokens issued by IdentityPlatform APIs in regionalized Firebase Auth, which can
// have expiry as low as 5 minutes. This should provide enough buffer to the Firebase SDKs for
// token usage before it expires.
private readonly TOKEN_EXPIRATION_BUFFER = 60_000;

// Any network calls will set this to true and prevent subsequent emulator
// initialization
Expand Down
Loading