By submitting an Issue to this repository, you agree to the terms within the Auth0 Code of Conduct.
Turning the jwt.sign callback into a promise with the built in node util.promisify() function doesn't accept an options object as the third argument
CODE
import jwt from 'jsonwebtoken';
import { promisify } from 'util';
const asyncSign = promisify(jwt.sign);
export async function encodeJWT(payload: string | object | Buffer): Promise<unknown> {
return await asyncSign(payload, JWT_SECRET, { expiresIn: '' });
}
ERROR
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
src/lib/hash.ts:40:47 - error TS2554: Expected 2 arguments, but got 3.
40 return await asyncSign(payload, JWT_SECRET, { expiresIn: '' });
~~~~~~~~~~~~~~~~~
Package.json
"@types/jsonwebtoken": "^8.3.8",
"jsonwebtoken": "^8.5.1",
"typescript": "^3.8.3"
Mac OS X Catalina
Visual Studio Code
TypeScript 3.8
jsonwebtoken 8.5
node v12.14.0
Wrap callback in a promise
Typescript
export function encodeJWT(payload: string | object | Buffer): Promise<unknown> {
return new Promise((resolve, reject) => {
jwt.sign(payload, JWT_SECRET, { expiresIn: '30d' }, (err, token) => {
if (err) return reject(err);
else return resolve(token);
});
});
}
Javascript
export function encodeJWT(payload) {
return new Promise((resolve, reject) => {
jwt.sign(payload, JWT_SECRET, { expiresIn: '30d' }, (err, token) => {
if (err) return reject(err);
else return resolve(token);
});
});
}
I was able to reproduce. The issue seems to be the overloading of the sign method and promisify basically picking the "first" instance of the overloaded sign method that appears in the definition https://github.com/DefinitelyTyped/DefinitelyTyped/blob/da534110efb3088d245ed9894cd28ef71191f6f2/types/jsonwebtoken/index.d.ts#L140.
Beside the workaround you've suggested, you could also try this:
const asyncSign = (
payload: string | Buffer | object,
secretOrPrivateKey: Secret,
options: SignOptions
) => promisify(sign);
This will effectively act as a "hint" for promisify to use the correct method signature.
Hello there @svnty :). Yet another solution is to do:
const signToken =
promisify<object, Secret, SignOptions>(sign);
signToken(payload, 'secret', jwtOptions);
This works for me
promisify(sign)({ ...payload }, cert, { algorithm: config.jwt.algorithm });
Append the sign options to the payload, it will work
Most helpful comment
I was able to reproduce. The issue seems to be the overloading of the
signmethod andpromisifybasically picking the "first" instance of the overloadedsignmethod that appears in the definition https://github.com/DefinitelyTyped/DefinitelyTyped/blob/da534110efb3088d245ed9894cd28ef71191f6f2/types/jsonwebtoken/index.d.ts#L140.Beside the workaround you've suggested, you could also try this:
This will effectively act as a "hint" for promisify to use the correct method signature.