From f34d0c4da2beb2e4f6f58dbf60a9f88d515c12bf Mon Sep 17 00:00:00 2001 From: Warren Parad Date: Thu, 18 Feb 2021 20:09:10 +0100 Subject: [PATCH] Enable version 2 service client tokens. --- package.json | 3 ++- src/serviceClientTokenProvider.js | 28 ++++++++++++++++++++++++---- yarn.lock | 5 +++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 64fce1d..373d1de 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "axios": "^0.21", + "jose": "^3.6.2", "jsonwebtoken": "^8.5", "jwk-to-pem": "^2.0.4" }, @@ -58,6 +59,6 @@ }, "homepage": "https://authress.io", "engines": { - "node": ">=10.12" + "node": ">=11.6" } } diff --git a/src/serviceClientTokenProvider.js b/src/serviceClientTokenProvider.js index 12c7411..aa940a9 100644 --- a/src/serviceClientTokenProvider.js +++ b/src/serviceClientTokenProvider.js @@ -1,4 +1,6 @@ const jwtManager = require('jsonwebtoken'); +const { default: JwtSigner } = require('jose/dist/node/cjs/jwt/sign'); +const { createPrivateKey } = require('crypto'); module.exports = function(accessKey) { return async () => { @@ -8,7 +10,18 @@ module.exports = function(accessKey) { const accessKeyBuffer = Buffer.from(accessKey, 'base64'); const accessKeyString = accessKeyBuffer.toString('base64') === accessKey ? accessKeyBuffer.toString('utf8') : accessKey; - const decodedAccessKey = JSON.parse(accessKeyString.trim()); + let decodedAccessKey; + let alg = 'RS256'; + try { + decodedAccessKey = JSON.parse(accessKeyString.trim()); + } catch (error) { + alg = 'EdDSA'; + decodedAccessKey = { + clientId: accessKey.split('.')[0], keyId: accessKey.split('.')[1], + audience: `${accessKey.split('.')[2]}.accounts.authress.io`, privateKey: accessKey.split('.')[3] + }; + } + const now = Math.round(Date.now() / 1000); const jwt = { aud: decodedAccessKey.audience, @@ -19,9 +32,16 @@ module.exports = function(accessKey) { exp: now + 60 * 60 * 24, scope: 'openid' }; - const options = { algorithm: 'RS256', keyid: decodedAccessKey.keyId }; - const token = await jwtManager.sign(jwt, decodedAccessKey.privateKey, options); - this.cachedKeyData = { token, expires: jwt.exp * 1000 }; + + if (alg === 'RS256') { + const options = { algorithm: 'RS256', keyid: decodedAccessKey.keyId }; + const token = await jwtManager.sign(jwt, decodedAccessKey.privateKey, options); + this.cachedKeyData = { token, expires: jwt.exp * 1000 }; + return token; + } + + const importedKey = createPrivateKey({ key: Buffer.from(decodedAccessKey.privateKey, 'base64'), format: 'der', type: 'pkcs8' }); + const token = await new JwtSigner(jwt).setProtectedHeader({ alg: 'EdDSA', kid: decodedAccessKey.keyId }).sign(importedKey); return token; }; }; diff --git a/yarn.lock b/yarn.lock index 1e67fa2..d4054db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1109,6 +1109,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +jose@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/jose/-/jose-3.6.2.tgz#e35ebe187306c14a0633b33b277a1550a3a947ee" + integrity sha512-JzqHr6UqydWv25HwLzRdBJgMetiPkDBE/WJSyJjhNwN3+GmcHu4yoUgRle0NNViCdfAYMf9DuOG8o+mUW/DXdg== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"