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 functionality of the Drawer component in material-ui v1.0 seems to be incompatible with TypeScript

Every time I try to utilize Drawer from [email protected] using typescript, I encounter the following error: TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Re ...

Using an array of objects as a data source for the Material Angular table

My user data is causing some issues and looks like this... [{"firstName":"Pinkie","lastName":"Connelly","username":"Darlene.Marvin","email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="19506a767b7c75464b7c77777c6b5971766d74 ...

Error in Typescript persists even after short-circuit evaluation is used

Kindly review the provided code sample type type1 = string[] | undefined; let variable1 : type1 = undefined; console.log(variable1 && variable1.length); Upon attempting to run this code in Typescript Playground, an error is generated stating Pro ...

Display issues with deeply nested components

I'm facing an issue with displaying the third nested component. Expected: Hello App Component Hello Nest-A Component Hello Nest-1 Component Hello Test-Z Component Actual: Hello App Component Hello Nest-A Component Hello Nest-1 Component Why ...

Encountered 'DatePickerProps<unknown>' error while attempting to develop a custom component using Material-UI and react-hook-form

Currently, I'm attempting to create a reusable component using MUI Datepicker and React Hook Form However, the parent component is throwing an error Type '{ control: Control<FieldValues, object>; name: string; }' is missing the follow ...

Incorporating jsbi into a TypeScript project while adhering to strict mode

I have been developing a TypeScript library that relies on native BigInts. While it functions perfectly in Chrome, I encountered some issues with Safari. After some research, I stumbled upon the jsbi "polyfill" that seems to solve this problem. Unfortunat ...

Executing a method during the initialization process in app.component.ts

One thing I've noticed is that the <app-root> component in Angular doesn't implement OnInit like all the other components. It may sound silly, but let's say I wanted to add a simple console.log('Hello World') statement to dis ...

Typescript's way of mocking fetch for testing purposes

I have a query regarding the following code snippet: import useCountry from './useCountry'; import { renderHook } from '@testing-library/react-hooks'; import { enableFetchMocks } from 'jest-fetch-mock'; enableFetchMocks(); i ...

Is it possible for FormArray to return null?

Hello there. I've attempted various methods, but none of them seem to be effective. Currently, I am working on this task where I need to start a formArray for emails. email: [testestest] However, what I have is: email: [testestest] I'm encoun ...

Creating a typescript type for contextual dispatch by leveraging the values of another interface

I am seeking to define a specific type for my "reducer" function. The "reducer" function I have takes in 2 parameters: the current state and the data sent in the dispatch context (to be used by the reducer). const reducer = ( state: any, props: { ...

Steps for styling the header of an Antd Collapse Panel

I'm attempting to modify the text color in the header of an ant panel. Below is the entire ant collapse component code: <Collapse accordion defaultActiveKey={defaultOpenPanel}> <StyledCollapsePanel key="tasksAssignedToMe" header={ ...

Incorporating CodeMirror into Angular2 using TypeScript

I've been working on integrating a CodeMirror editor into an Angular2 project, but I'm encountering some issues with the instantiation of the editor. Here is my code snippet: editor.component.ts import {Component} from 'angular2/core' ...

How to calculate the sum of all values in a FormArray in Angular

I am trying to retrieve the input values from each row and then calculate the sum of these rows. Here is my HTML code: <ng-container formArrayName="cap_values"> <tbody *ngFor="let item of capValues.controls; let i=index" [formGroupName]="i"& ...

Using Typescript to pass an optional parameter in a function

In my request function, I have the ability to accept a parameter for filtering, which is optional. An example of passing something to my function would be: myFunc({id: 123}) Within the function itself, I've implemented this constructor: const myFunc ...

Is it possible to use string indexes with jQuery each method in Typescript?

When running a jQuery loop in Typescript, I encountered an issue where the index was being reported as a string. $.each(locations, (index, marker) => { if(this.options && this.options.bounds_marker_limit) { if(index <= (this.opt ...

Tips for inserting a component into a div selector using Angular 2

Could someone please help me figure out how to inject a component into a div selector using a class or id? I'm familiar with injecting components into other components, but not sure how to do it specifically within a div. Any guidance would be greatly ...

When embedding HTML inside an Angular 2 component, it does not render properly

Currently, I am utilizing a service to dynamically alter the content within my header based on the specific page being visited. However, I have encountered an issue where any HTML code placed within my component does not render in the browser as expected ( ...

Generic Typescript Placeholder Design

Imagine you have the following data: const dataA = { name: "John", age: 25, attributes: {specificA: "hello", specificA2: 14, nonspecific:"Well"}, } const dataB = { name: "Lisa", age: 38, attributes: {spe ...

Observable<void> fails to trigger the subscriber

I am currently facing a challenge with implementing a unit test for an Observable in order to signal the completion of a process. While there is no asynchronous code in the logout function yet, I plan to include it once the full logic is implemented. The m ...

An issue arising with the TypeScript antlr4ts listener type

I am currently attempting to incorporate the antlr4 parser into an angular project. Within a dataservice class, there is a function being called that appears as follows: parseRule() { const ruleString = ' STRING TO PARSE'; const inputS ...