From dfce32b3567e02d93241fdca623e0ec8193db3fb Mon Sep 17 00:00:00 2001 From: Jonah Back Date: Mon, 18 Jan 2021 14:09:23 -0800 Subject: [PATCH] Address review comments around algorithm being used, typescript ignore --- plugins/auth-backend/package.json | 8 +----- .../auth-backend/src/identity/TokenFactory.ts | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index f189f8078f..380b7da6b0 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -18,13 +18,7 @@ }, "jest": { "moduleNameMapper": { - "jose/jwt/sign": "/../node_modules/jose/dist/node/cjs/jwt/sign", - "jose/jwt/verify": "/../node_modules/jose/dist/node/cjs/jwt/verify", - "jose/jwk/from_key_like": "/../node_modules/jose/dist/node/cjs/jwk/from_key_like", - "jose/jwk/parse": "/../node_modules/jose/dist/node/cjs/jwk/parse", - "jose/util/base64url": "/../node_modules/jose/dist/node/cjs/util/base64url", - "jose/util/decode_protected_header": "/../node_modules/jose/dist/node/cjs/util/decode_protected_header", - "jose/util/generate_secret": "/../node_modules/jose/dist/node/cjs/util/generate_secret" + "^jose/(.*)$": "/../node_modules/jose/dist/node/cjs/$1" } }, "keywords": [ diff --git a/plugins/auth-backend/src/identity/TokenFactory.ts b/plugins/auth-backend/src/identity/TokenFactory.ts index 8cf7c358d6..65f9a07eb1 100644 --- a/plugins/auth-backend/src/identity/TokenFactory.ts +++ b/plugins/auth-backend/src/identity/TokenFactory.ts @@ -18,7 +18,7 @@ import moment from 'moment'; import { TokenIssuer, TokenParams, KeyStore, AnyJWK } from './types'; import parseJwk, { JWK } from 'jose/jwk/parse'; import SignJWT from 'jose/jwt/sign'; -import generateSecret from 'jose/util/generate_secret'; +import generateKeyPair from 'jose/util/generate_key_pair'; import fromKeyLike from 'jose/jwk/from_key_like'; import { Logger } from 'winston'; import { v4 as uuid } from 'uuid'; @@ -129,12 +129,20 @@ export class TokenFactory implements TokenIssuer { const promise = (async () => { // This generates a new signing key to be used to sign tokens until the next key rotation - const key = await generateSecret('HS256'); + const key = await generateKeyPair('ES256'); const kid = uuid(); - const jwk = await fromKeyLike(key); - jwk.kid = kid; - jwk.alg = 'HS256'; + const jwk = await fromKeyLike(key.privateKey); + // @ts-ignore https://github.com/microsoft/TypeScript/issues/13195 - + // JOSE Library provides optional for most fields - and TS does not distinguish between missing/undefined. + // Because AnyJWK requires keys to have type "string", this throws a TypeError - though in practice, if the field + // is undefined, JOSE will not send it back as key. + const storedJwk: AnyJWK = { + ...jwk, + alg: 'ES256', + kid: kid, + use: 'sig', + }; // We're not allowed to use the key until it has been successfully stored // TODO: some token verification implementations aggressively cache the list of keys, and // don't attempt to fetch new ones even if they encounter an unknown kid. Therefore we @@ -142,14 +150,9 @@ export class TokenFactory implements TokenIssuer { // the new one. This also needs to be implemented cross-service though, meaning new services // that boot up need to be able to grab an existing key to use for signing. this.logger.info(`Created new signing key ${jwk.kid}`); - await this.keyStore.addKey({ - // @ts-ignore - use: 'sig', - ...jwk, - }); - + await this.keyStore.addKey(storedJwk); // At this point we are allowed to start using the new key - return jwk; + return storedJwk; })(); this.privateKeyPromise = promise;