diff --git a/packages/backend-common/src/tokens/ServerTokenManager.test.ts b/packages/backend-common/src/tokens/ServerTokenManager.test.ts index 2827634aac..30d3571606 100644 --- a/packages/backend-common/src/tokens/ServerTokenManager.test.ts +++ b/packages/backend-common/src/tokens/ServerTokenManager.test.ts @@ -179,21 +179,21 @@ describe('ServerTokenManager', () => { const { token: token1 } = await tokenManager.getToken(); await expect(tokenManager.authenticate(token1)).resolves.not.toThrow(); - // Less than ten minutes before expiry, it still returns the same token - jest.advanceTimersByTime(49 * 60 * 1000); + // Right before the reissue timeout, it still returns the same token + jest.advanceTimersByTime(9 * 60 * 1000); const { token: token1Again } = await tokenManager.getToken(); expect(token1).toEqual(token1Again); await expect(tokenManager.authenticate(token1)).resolves.not.toThrow(); - // Right before the expiry, the old ones are still valid but returning a new token - jest.advanceTimersByTime(10 * 60 * 1000); + // Right after the reissue timeout, the old ones are still valid but returning a new token + jest.advanceTimersByTime(2 * 60 * 1000); const { token: token2 } = await tokenManager.getToken(); expect(token1).not.toEqual(token2); await expect(tokenManager.authenticate(token1)).resolves.not.toThrow(); await expect(tokenManager.authenticate(token2)).resolves.not.toThrow(); - // After expiry, the newest one is still valid - jest.advanceTimersByTime(2 * 60 * 1000); + // After expiry of the first one, the newest one is still valid + jest.advanceTimersByTime(52 * 60 * 1000); await expect( tokenManager.authenticate(token1), ).rejects.toThrowErrorMatchingInlineSnapshot( diff --git a/packages/backend-common/src/tokens/ServerTokenManager.ts b/packages/backend-common/src/tokens/ServerTokenManager.ts index 65354f270f..1915330d26 100644 --- a/packages/backend-common/src/tokens/ServerTokenManager.ts +++ b/packages/backend-common/src/tokens/ServerTokenManager.ts @@ -23,7 +23,8 @@ import { TokenManager } from './types'; const TOKEN_ALG = 'HS256'; const TOKEN_SUB = 'backstage-server'; -const TOKEN_EXPIRY = Duration.fromObject({ hours: 1 }); +const TOKEN_EXPIRY_AFTER = Duration.fromObject({ hours: 1 }); +const TOKEN_REISSUE_AFTER = Duration.fromObject({ minutes: 10 }); /** * A token manager that issues static dummy tokens and never fails @@ -151,7 +152,9 @@ export class ServerTokenManager implements TokenManager { const jwt = await new SignJWT({}) .setProtectedHeader({ alg: TOKEN_ALG }) .setSubject(TOKEN_SUB) - .setExpirationTime(DateTime.now().plus(TOKEN_EXPIRY).toUnixInteger()) + .setExpirationTime( + DateTime.now().plus(TOKEN_EXPIRY_AFTER).toUnixInteger(), + ) .sign(this.signingKey); return { token: jwt }; }); @@ -162,7 +165,7 @@ export class ServerTokenManager implements TokenManager { .then(() => { setTimeout(() => { this.currentTokenPromise = undefined; - }, TOKEN_EXPIRY.minus({ minutes: 5 }).toMillis()); + }, TOKEN_REISSUE_AFTER.toMillis()); }) .catch(() => { this.currentTokenPromise = undefined;