'making handleRequest an async method on passportjs guard

@Injectable()
export class RefreshAuthGuard extends JwtAuthGuard {
    constructor(
        private readonly jwtService: JwtService,
    ) {
        super();
    }
    public handleRequest(err: any, user: any, info: Error, ctx: any): any {
        if (err || !user) {
            if (info.name === 'TokenExpiredError') {
                const request: Request = ctx.getRequest();
                const headers: IHttpRequestHeaders = request.headers as IHttpRequestHeaders;
                const refresh_token = headers.refresh_token;
                if (!this.isValidRefreshToken(refresh_token)) {
                    throw new HttpException('Invalid refresh token', HttpStatus.UNAUTHORIZED);
                }
            } else {
                throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);
            }
        } else {
            throw new HttpException('Expired tokens only', HttpStatus.FORBIDDEN);
        }
    }

    private isValidRefreshToken(refresh_token: string): boolean {
        return !!refresh_token;
    }
}

Problem:

If I add async to the method and make it return Promise<any> for now it says:

Property 'handleRequest' in type 'RefreshAuthGuard' is not assignable to the same property in base type 'JwtAuthGuard'.Type '(err: any, user: any, info: Error, ctx: any) => Promise<any>' is not assignable to type '<TUser = any>(err: any, user: any, info: any, context: any, status?: any) => TUser'. Type 'Promise<any>' is not assignable to type 'TUser'

I really need these methods to be async so that I could retrieve user's refresh_token from the DB and validate it inside this guard. I need these operations async.

EDIT:

this piece is from the nestjs source code:

export declare type IAuthGuard = CanActivate & {
    logIn<TRequest extends {
        logIn: Function;
    } = any>(request: TRequest): Promise<void>;
    handleRequest<TUser = any>(err: any, user: any, info: any, context: any, status?: any): TUser;
};
export declare const AuthGuard: (type?: string | string[]) => Type<IAuthGuard>;

So it looks that the method can't be asynchronous...



Solution 1:[1]

I realize this an old question, however, you need to do this in your jwt strategy which extends the default PassportStrategy and can offer your own custom validate method, which can be asynchronous...

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    private authService: AuthService
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.jwt_token_secret,
    });
  }

  async validate(payload: any) {
    const user = await this.authService.validateUserFromUsername(payload.username);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

Solution 2:[2]

Just add ts-ignore command above your handleRequest function and make it an async function like bellow:

// @ts-ignore: Unreachable code error
   async handleRequest(err, user, info: Error, context: ExecutionContext) {
       // Your code
   }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 navanjr
Solution 2 Pejman Hadavi