diff --git a/plugins/auth-backend/src/identity/TokenFactory.test.ts b/plugins/auth-backend/src/identity/TokenFactory.test.ts index a7e7760dcf..4303401ee6 100644 --- a/plugins/auth-backend/src/identity/TokenFactory.test.ts +++ b/plugins/auth-backend/src/identity/TokenFactory.test.ts @@ -60,11 +60,11 @@ function jwtKid(jwt: string): string { describe('TokenFactory', () => { it('should issue valid tokens signed by a listed key', async () => { - const keyDuration = 5; + const keyDurationSeconds = 5; const factory = new TokenFactory({ issuer: 'my-issuer', keyStore: new MemoryKeyStore(), - keyDuration, + keyDurationSeconds, logger, }); @@ -87,7 +87,7 @@ describe('TokenFactory', () => { iat: expect.any(Number), exp: expect.any(Number), }); - expect(payload.exp).toBe(payload.iat + keyDuration * 1000); + expect(payload.exp).toBe(payload.iat + keyDurationSeconds * 1000); }); it('should generate new signing keys when the current one expires', async () => { @@ -97,7 +97,7 @@ describe('TokenFactory', () => { const factory = new TokenFactory({ issuer: 'my-issuer', keyStore: new MemoryKeyStore(), - keyDuration: 5, + keyDurationSeconds: 5, logger, }); diff --git a/plugins/auth-backend/src/identity/TokenFactory.ts b/plugins/auth-backend/src/identity/TokenFactory.ts index a9a8ad5a30..c4c259ed22 100644 --- a/plugins/auth-backend/src/identity/TokenFactory.ts +++ b/plugins/auth-backend/src/identity/TokenFactory.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import moment from 'moment'; import { TokenIssuer, TokenParams, KeyStore, AnyJWK } from './types'; import { JSONWebKey, JWK, JWS } from 'jose'; import { Logger } from 'winston'; @@ -28,7 +29,7 @@ type Options = { /** Key store used for storing signing keys */ keyStore: KeyStore; /** Expiration time of signing keys in seconds */ - keyDuration: number; + keyDurationSeconds: number; }; /** @@ -49,16 +50,16 @@ export class TokenFactory implements TokenIssuer { private readonly issuer: string; private readonly logger: Logger; private readonly keyStore: KeyStore; - private readonly keyDuration: number; + private readonly keyDurationSeconds: number; - private keyExpiry?: number; + private keyExpiry?: moment.Moment; private privateKeyPromise?: Promise; constructor(options: Options) { this.issuer = options.issuer; this.logger = options.logger; this.keyStore = options.keyStore; - this.keyDuration = options.keyDuration; + this.keyDurationSeconds = options.keyDurationSeconds; } async issueToken(params: TokenParams): Promise { @@ -68,7 +69,7 @@ export class TokenFactory implements TokenIssuer { const sub = params.claims.sub; const aud = 'backstage'; const iat = Math.floor(Date.now() / MS_IN_S); - const exp = iat + this.keyDuration * MS_IN_S; + const exp = iat + this.keyDurationSeconds * MS_IN_S; this.logger.info(`Issuing token for ${sub}`); @@ -89,7 +90,7 @@ export class TokenFactory implements TokenIssuer { for (const key of keys) { // Allow for a grace period of another full key duration before we remove the keys from the database - const expireAt = key.createdAt.add(3 * this.keyDuration, 'seconds'); + const expireAt = key.createdAt.add(3 * this.keyDurationSeconds, 's'); if (expireAt.isBefore()) { expiredKeys.push(key); } else { @@ -116,14 +117,14 @@ export class TokenFactory implements TokenIssuer { private async getKey(): Promise { // Make sure that we only generate one key at a time if (this.privateKeyPromise) { - if (this.keyExpiry && Date.now() < this.keyExpiry) { + if (this.keyExpiry?.isAfter()) { return this.privateKeyPromise; } this.logger.info(`Signing key has expired, generating new key`); delete this.privateKeyPromise; } - this.keyExpiry = Date.now() + this.keyDuration * MS_IN_S; + this.keyExpiry = moment().add(this.keyDurationSeconds, 'seconds'); const promise = (async () => { // This generates a new signing key to be used to sign tokens until the next key rotation const key = await JWK.generate('EC', 'P-256', { diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index dcd650c858..68b2d31032 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -37,7 +37,7 @@ export async function createRouter( const logger = options.logger.child({ plugin: 'auth' }); const baseUrl = `${options.config.getString('backend.baseUrl')}/auth`; - const keyDuration = 3600; + const keyDurationSeconds = 3600; const keyStore = await DatabaseKeyStore.create({ database: options.database, @@ -45,7 +45,7 @@ export async function createRouter( const tokenIssuer = new TokenFactory({ issuer: baseUrl, keyStore, - keyDuration, + keyDurationSeconds, logger: logger.child({ component: 'token-factory' }), });