seanpmaxwell / express-generator-typescript

Create a new express app similar to express-generator but with TypeScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting an error when calling "jsonwebtoken.verify"

digizen opened this issue · comments

Just ran the generator. The generated app is throwing an error src/shared/JwtService.ts - the jsonwebtoken.verify has parameters that aren't matching.

I'm running Win10, Node v12, Typescript 3.6.3.

The error message:

`src/shared/JwtService.ts:45:51 - error TS2769: No overload matches this call.
Overload 1 of 3, '(token: string, secretOrPublicKey: Secret, options?: VerifyOptions | undefined): string | object', gave the following error.
Type '(err: VerifyErrors, decoded: string | object) => void' has no properties in common with type 'VerifyOptions'.
Overload 2 of 3, '(token: string, secretOrPublicKey: string | Buffer | { key: string | Buffer; passphrase: string; } | GetPublicKeyOrSecret, callback?: VerifyCallback | undefined): void', gave the following error.
Argument of type '(err: VerifyErrors, decoded: object | string) => void' is not assignable to parameter of type 'VerifyCallback'.
Types of parameters 'err' and 'err' are incompatible.
Type 'JsonWebTokenError | NotBeforeError | TokenExpiredError | null' is not assignable to type 'VerifyErrors'.
Type 'null' is not assignable to type 'VerifyErrors'.
Overload 3 of 3, '(token: string, secretOrPublicKey: string | Buffer | { key: string | Buffer; passphrase: string; } | GetPublicKeyOrSecret, options?: VerifyOptions | undefined, callback?: VerifyCallback | undefined): void', gave the following error.
Type '(err: VerifyErrors, decoded: string | object) => void' has no properties in common with type 'VerifyOptions'.

45 jsonwebtoken.verify(jwt, this.secret, (err: VerifyErrors, decoded: object | string) => {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

at createTSError (C:\code\js\fullstack_express\express_test\node_modules\ts-node\src\index.ts:434:12)
at reportTSError (C:\code\js\fullstack_express\express_test\node_modules\ts-node\src\index.ts:438:19)
at getOutput (C:\code\js\fullstack_express\express_test\node_modules\ts-node\src\index.ts:578:36)
at Object.compile (C:\code\js\fullstack_express\express_test\node_modules\ts-node\src\index.ts:775:32)
at Module.m._compile (C:\code\js\fullstack_express\express_test\node_modules\ts-node\src\index.ts:858:43)
at Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Object.require.extensions.<computed> [as .ts] (C:\code\js\fullstack_express\express_test\node_modules\ts-node\src\index.ts:861:12)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Module.require (internal/modules/cjs/loader.js:852:19)`

I just ran it and it worked fine for me. Did you use npm run start:dev? I'm on node v12.13.0

Yep, that's exactly the option I tried. I also tried same with Ubuntu (I have WSL installed), and it gave me the same error message.

My Ubuntu Node version is 14.3.0, and my Windows 10 Node version is 12.14.0.

The command I used to start the project was:
npx express-generator-typescript --with-auth express_test2

and you downloaded express-generator-typescript with npx express-generator-typescript?

Yep - the exact command line was:
npx express-generator-typescript --with-auth express_test2

I started poking around. VS.Code only shows the one error.

This is the generated code:

    public decodeJwt(jwt: string): Promise<IClientData> {
        return new Promise((res, rej) => {
            jsonwebtoken.verify(jwt, this.secret, (err: VerifyErrors, decoded: object | string) => {
                return err ? rej(this.VALIDATION_ERROR) : res(decoded as IClientData);
            });
        });

There are three ways to call the verify function:

export function verify(token: string, secretOrPublicKey: Secret, options?: VerifyOptions): object | string;

/**
 * Asynchronously verify given token using a secret or a public key to get a decoded token
 * token - JWT string to verify
 * secretOrPublicKey - A string or buffer containing either the secret for HMAC algorithms,
 * or the PEM encoded public key for RSA and ECDSA. If jwt.verify is called asynchronous,
 * secretOrPublicKey can be a function that should fetch the secret or public key
 * [options] - Options for the verification
 * callback - Callback to get the decoded token on
 */
export function verify(
    token: string,
    secretOrPublicKey: Secret | GetPublicKeyOrSecret,
    callback?: VerifyCallback,
): void;
export function verify(
    token: string,
    secretOrPublicKey: Secret | GetPublicKeyOrSecret,
    options?: VerifyOptions,
    callback?: VerifyCallback,
): void;

I'ma assuming that it's the second overload we're interested in. The error message says:

Overload 2 of 3, '(token: string, secretOrPublicKey: string | Buffer | { key: string | Buffer; passphrase: string; } | GetPublicKeyOrSecret, callback?: VerifyCallback | undefined): void', gave the following error.
    Argument of type '(err: jsonwebtoken.VerifyErrors, decoded: string | object) => void' is not assignable to parameter of type 'VerifyCallback'.
      Types of parameters 'err' and 'err' are incompatible.
        Type 'JsonWebTokenError | NotBeforeError | TokenExpiredError | null' is not assignable to type 'VerifyErrors'.
          Type 'null' is not assignable to type 'VerifyErrors'.

This is the signature of VerifyErrors:

export type VerifyErrors =
    | JsonWebTokenError
    | NotBeforeError
    | TokenExpiredError;

I haven't yet figured it out yet, but it looks like the err parameter being passed in may be nullable, which is incompatible with the VerifyErrors signature.

Ok, I got the program to work by modify the signature passed in. I don't understand Typescript/this function enough to know if this is correct or not - can you please take a look? The command "npm run start:dev" does work now though.

I had to modify both parameters - once I added the "| null" to the end of the first parameter, it started complaining about the second one.

    public decodeJwt(jwt: string): Promise<IClientData> {
        return new Promise((res, rej) => {
            jsonwebtoken.verify(jwt, this.secret, (err: VerifyErrors | null, decoded: object | undefined) => {
                return err ? rej(this.VALIDATION_ERROR) : res(decoded as IClientData);
            });
        });
    }

Hey thanks so much for pointing this out. I neglected to use the --with-auth option last time. The callback for the jsonwebtoken library was updated so the callback being passed to it stopped working. I updated express-generator-typescript to a new version. Try it now and let me know if it works for you.

Yep, that fixed it. I was only slightly off on the signature too :). You did "decoded? object" and I had "decoded: object | undefined". Would my type have worked?

those are equivalent

I installed jsonwebtoken

import jwt from "jsonwebtoken"
const decode = jwt.verify(user.token, process.env.JWT_SECRET)

Worked for me