Implementing handleRequest as an asynchronous function within the 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;
    }
}

Challenge:

If I were to add the async keyword to the method and change its return type to Promise<any>, I encounter the following error message:

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

I am in need of making these methods asynchronous in order to retrieve a user's refresh token from the database and validate it within this guard. Asynchronous operations are crucial for my requirements.

UPDATE:

This excerpt is taken from the source code of NestJS:

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>;

It appears that the method cannot be made asynchronous...

Answer №1

Although this question may be old, it is important to implement the necessary logic in your jwt strategy. This custom strategy extends the default PassportStrategy and allows you to define a unique validate method that can be executed asynchronously...

@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;
  }
}

Answer №2

To address the issue of unreachable code error, you can simply include the ts-ignore command above your handleRequest function and convert it into an async function as shown below:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The UI elements are failing to reflect the changes in the data

In an attempt to establish communication between three components on a webpage using a data service, I have a Create/Edit component for adding events, a "next events" component for accepting/declining events, and a Calendar component for displaying upcomin ...

Angular 5 - Jasmine Tests explained: Encounter with the puzzling error message: "Error: Provider for the NgModule 'DynamicTestModule' is invalid, as only instances of Provider and Type are permitted"

I'm having trouble running tests on a component class. Here's the error message from the stack: Error: Invalid provider for the NgModule 'DynamicTestModule' - only instances of Provider and Type are allowed, got: [AlertModaldataCompon ...

Encountering difficulties with installing bootstrap-vue

While attempting to integrate Bootstrap-Vue into my project that includes Vuex, Vue-Router, TypeScript, and Babel, I encounter an error in the browser. To replicate docker run -it --rm -p 8080:8080 node:17.7.2-alpine yarn global add @vue/cli vue create ...

Transforming AngularJS 2.0 code into ES6 syntax

Successfully implemented the AngularJS 2.0 5 Minute Quickstart in my IntelliJ IDEA 14.1.4 following a helpful Stackoverflow Answer on AngularJS 2.0 TypeScript Intellij idea (or webstorm) - ES6 import syntax. However, it seems to focus on compiling TypeScr ...

Encountering an issue while trying to import the validator module in NextJS 13

I encountered a peculiar issue while trying to import a module. Nextjs presented the following error message: ./application/sign_in/sign_in_store.ts:2:0 Module not found: Can't resolve 'validator' 1 | import { createEvent, createStore } fr ...

Unable to initiate ngModelChange event during deep cloning of value

I've been struggling to calculate the sum of row values, with no success. My suspicion is that the issue lies in how I am deep cloning the row values array when creating the row. const gblRowVal1 = new GridRowValues(1, this.color, this.headList ...

Looking to retrieve the AssetLoadedFunc properties in the LoadAssets function? Wondering if you should use TypeScript or JavaScript

When I invoke this.AssetLoadedFunc within the function LoadAssets(callback, user_data) LoadAssets(callback, user_data) { this.glg.LoadWidgetFromURL("assets/Js/scrollbar_h.g", null, this.AssetLoaded, { name: "scrollb ...

Retrieve all values of a specific enum type in TypeScript

When working with Typescript, I am looking to retrieve all values of an enum type and store them in an array. In C#, a similar method would look like this: public static TEnum[] GetValues<TEnum>() where TEnum : Enum { return Enum.GetValues(typeof ...

What is the process for exporting a class to a module and then importing it into another module using TypeScript within an Angular environment?

I have a class called IGeneric that is exported to module A and imported into module B. However, I am unable to use this exported class in module B. Please note that the exported class is not a component, directive, or service; it is a plain TypeScript cl ...

Tips for passing a query parameter in a POST request using React.js

I am new to working with ReactJS and I have a question about passing boolean values in the URL as query parameters. Specifically, how can I include a boolean value like in a POST API call? The endpoint for the post call is API_SAMPLE: "/sample", Here is ...

React - Login page briefly appears while loading

Hello, I have built a React application that consists of a Login page, Loading page, and the main app itself. However, there is a small issue where after a user logs in, instead of smoothly transitioning to the Loading page until the data is loaded, the L ...

What specific type should be used for validations when incorporating express-validator imperative validations?

Having trouble implementing express-validator's imperative validations in TypeScript because the type for validations cannot be found. // reusable function for multiple routes const validate = validations => { return async (req, res, next) => ...

Using TypeScript to automatically determine the argument type of a function by analyzing the return type of a different function

I am working on an interface with the following structure: interface Res<R = any> { first?(): Promise<R>; second(arg: { response: R }): void; } However, I noticed that when creating a plain object based on this interface, the response ...

Serving sourcemaps for a web extension in Firefox: A step-by-step guide

Currently in the process of developing a web extension using TypeScript, I have encountered an issue with sourcemaps not loading properly. The use of parcel to bundle my extension has made the bundling process simple and straightforward. However, while the ...

How can you make sure that VS Code always utilizes relative paths for auto imports in TypeScript?

VS Code has been automatically importing everything using Node-like non-relative paths relative to baseUrl, which is not the desired behavior. Is there a way to instruct VS Code to import everything with relative paths, excluding Node modules? Removing t ...

Transform a JSON array into an array of objects using typescript

I have a JSON array that I need to convert into an object type array JSON array [ 0:{code: "00125", scheme: "0001", plotNumber: "125", propType: "001", plotType: "001"} 1:{code: "190", scheme: "0001", plotNumber: "NA 190", propType: "001", plotType: "0 ...

In Deno, it is possible to confirm that a variable is an instance of a String

I'm having trouble asserting instances of string in Deno: import { assertInstanceOf } from "https://deno.land/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2642405050405e445e59445e">[email protected]</a& ...

Inspecting tRPC routing for examination purposes

Introduction Within my API, it is essential to authenticate the caller following input validation. The authorization for certain endpoints relies on details provided in the input parameters, such as the specific server-side resource being accessed and the ...

Chart of commitments and potential outcomes

I am in the early stages of learning about promises and I am struggling to understand how to write code correctly. Here is an overview of what the program should do: Retrieve a list of item types (obtained through a promise) Loop through each item type to ...

The JSON.stringify method in TypeScript/JavaScript does not align with the json-String parameter or request body in a Java controller

Currently, I am utilizing jdk 1.8 and have a rest endpoint in my Java controller: @PostMapping("/filters") public ResponseEntity<StatsDTO> listWithFilter( @RequestBody(required = false) String filter ) { try { ............... } } A test sn ...