Moving from 6.1.2 to 7.4.2 breaks
nsshunt opened this issue · comments
When I upgraded from v 6.1.2 to 7.4.2 I get this error;
TypeError: cb is not a function
Error occurs within expressJwtSecret @ highlighted line
module.exports.expressJwtSecret = function (options) {
if (options === null || options === undefined) {
throw new ArgumentError('An options object must be provided when initializing expressJwtSecret');
}
const client = new JwksClient(options);
const onError = options.handleSigningKeyError || handleSigningKeyError;
return function secretProvider(req, header, payload, cb) {
if (!header || !supportedAlg.includes(header.alg)) {
### return cb(null, null);
}
client.getSigningKey(header.kid)
.then(key => {
cb(null, key.publicKey || key.rsaPublicKey);
}).catch(err => {
onError(err, (newError) => cb(newError, null));
});
};
};
In 7.2.1, the secretProvider(req, header, payload, cb) gets;
req - ok (appears to be the req object)
header - this is actually the decoded token
payload = undefined
cd = undefined
So the caller is passing the wrong parameters.
Further, the caller is using 'option 3' when invoking this function.
Can confirm that it also breaks for me too after simply upgrading (and changing the imports). I just get a "expired token" error every time
The doc was outdated in 7.2.1, sorry about that. I made a major version (v7) because there are breaking changes. I fixed the readme arround 7.4
The secret
function receives two parameters only:
req
: the express.js requesttoken
: containspayload
andheader
https://github.com/auth0/express-jwt#retrieve-key-dynamically
in your case, your function can be replaced to this:
module.exports.expressJwtSecret = function (options) {
if (options === null || options === undefined) {
throw new ArgumentError('An options object must be provided when initializing expressJwtSecret');
}
const client = new JwksClient(options);
const onError = options.handleSigningKeyError || handleSigningKeyError;
return function secretProvider(req, token) {
const { header } = token;
if (!header || !supportedAlg.includes(header.alg)) {
return;
}
return client.getSigningKey(header.kid)
.then(key => {
return key.publicKey || key.rsaPublicKey;
}).catch(err => {
return new Promise((resolve, reject) => {
onError(err, (newError) => reject(newError));
});
});
}
};
+1, rolled back until this integration is fixed
The following rough replacement works for us for now until the integration is fixed. (I removed the options
check and onError
callback, as neither are needed in our case.)
import { GetVerificationKey } from 'express-jwt';
import { Jwt, Secret } from 'jsonwebtoken';
import { ExpressJwtOptions, JwksClient } from 'jwks-rsa';
export function expressJwtSecret(options: ExpressJwtOptions): GetVerificationKey {
const supportedAlg = require('jwks-rsa/src/integrations/config.js') as string[];
const client = new JwksClient(options);
return async function secretProvider(_req, token: Jwt | undefined): Promise<Secret> {
if (token) {
const { header } = token;
if (header && supportedAlg.includes(header.alg)) {
const key = await client.getSigningKey(token.header.kid);
return key.getPublicKey();
}
}
return '';
};
}
We're currently on:
"express-jwt": "7.4.3",
"jsonwebtoken": "8.5.1",
"jwks-rsa": "2.0.5",
"@types/jsonwebtoken": "8.5.8",
thanks for the heads up. I will try to fix jwks-rsa
I just send a PR, you can use npm i "jfromaniello/node-jwks-rsa#express_jwt_7"
until it gets merged.
Fixed in jwks-rsa@2.1
Thanks a lot for the fix, José!
@jfromaniello, there is a small typing issue. The newest versions of express-jwt use GetVerificationKey
as the type of this callback. SecretCallbackLong
seems to be the interface that was used by @types/express-jwt
up to express-jwt@7.
@rene-leanix I don't understand this.. Where is that SecretCallbackLong
? Thanks!
@jfromaniello, it's being imported here and used here. This should be changed to GetVerificationKey
. (SecretCallback
may also need to be replaced.)
Missing interface definitions are just interpreted as any
, so shouldn't lead to TS errors. In our case, ESLint picked this up as we've got a rule to avoid assignments of any
types. A temporary workaround was to cast it to GetVerificationKey
.
@rene-leanix you are absolutely right. I was able to reproduce the issue ,but as I wanted to leave jwks-rsa compatible with the previous version of express-jwt , I added a type alias for SecretCallback
and SecretCallbackLong
.
So, the fix the issue just install express-jwt@7.6
.