Exploring the req.user property in an Express application with TypeScript and Passport

I'm new to working with Express and I'm currently developing an authentication feature using email and password.

The authentication process is complete, but now I'm looking to secure the API routes based on user roles. Once authenticated, when I use console.log(req.user), I can see the user properties listed below.

{
  firstName: 'test',
  lastName: 'test',
  email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f084958384b09588919d809c95de939f9d">[email protected]</a>',
  password: 'password',
  role: 'user',
  createdAt: '2022-08-31T05:46:07.573Z',
  updatedAt: '2022-08-31T05:46:07.573Z'
}

However, when I attempt conditional branching with req.user.role, I receive an error indicating that it's undefined.

Property 'role' does not exist on type 'User'.ts(2339)

The same issue occurs if I try to access the property as 'req.user.attributes.role', resulting in it being undefined.

In addition, there's an error in the "passport.deserializeUser" section when using the following URL method.

More details here

Argument of type 'User' is not assignable to parameter of type 'false | User | null | undefined'.
  Type 'import("/Users/takeshi/FanFundBackEnd/db/entity/user").default' is not assignable to type 'Express.User'.
    Types of property 'role' are incompatible.
      Type 'import("/Users/takeshi/FanFundBackEnd/db/entity/user").UserRole | undefined' is not assignable to type 'string'.
        Type 'undefined' is not assignable to type 'string'.ts(2345)

Any suggestions on how to properly access the property of req.user?


isAdmin.ts => If the user type is 'user', return HTTP status 401.


export const isAdmin = (req: Request, res: Response, next: NextFunction) => {
  if (req.user.role != 'user') {
// Error: Property 'role' does not exist on type 'User'.ts(2339)
    console.log('Check User type is not user')
    next();
  }
  res.status(401).json({ "message": "Unauthorized, Check Your User Type" });
};


passportjs

const local = new Strategy({
  usernameField: 'email',
  passwordField: 'password'
}, async (email, password, done) => {
  try {
    const user = await UserController.getUser(email);
    if (!user) {
      console.log("unknown User")
      return done(null, false, { message: 'Unknown User' });
    }
    const c = user.password!;
    if (await bcrypt.compare(password, c.toString())){
      return done(null, user);
    } else {
      console.log("invalid password")
      return done(null, false, { message: 'Invalid password' });
    }
  } catch (error) {
    return done(error, null);
  }
});

passport.serializeUser((user, done) => {
  console.log('serialize', user);
  done(null, user);
});

passport.deserializeUser(async (user: User, done) => {
  console.log('deserialize');
  if (user) {
    done(null, user);
  } else {
    throw new Error('User does not exist');
  }
  
});

passport.use(local);

Answer №1

If you want to enhance the Express types object,

Check out this insightful post on extending the Express Request Object in TypeScript:

Informative article shared by a trusted source

In your specific scenario, consider expanding the Express.User interface:

import usertypes from './usertypes'
export {};
declare global {
 namespace Express {
  export interface User {
   data?: usertypes;
  }
 }
}

After implementing these changes, you can easily retrieve information using user.data?.role

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

I keep getting the error message "Element is missing a 'key' prop", even though I have already included a key in my loop. What could be the issue here?

Every <td> and <tr> in my code has a unique key assigned to it. Check out the complete code of my component below: export default function TableComponent( data: any ) { const columnNames = Object.keys(data.data); const rowIndices = Obj ...

Examining the status of child components in Angular

Within my codebase, there exists a Parent component that contains multiple instances of the Child component. Each child component dynamically decides whether or not to render its content based on various user settings and other factors. In the HTML file o ...

Expanding declaration files in TypeScript to include third-party libraries

Is there a way to customize third-party declaration files? For instance, I am looking to enhance Context from @types/koa by adding a new field (resource) to it. I attempted the following: // global.d.ts declare namespace koa { interface Context { ...

I'm looking for a clever approach in Typescript to effectively manage intricate union type challenges when working with the Notion SDK

In my TypeScript project, I am currently working on a function to clone a specific block or page in Notion through the API. Although there is no direct endpoint available for duplicating pages programmatically, I have taken it upon myself to try and create ...

Show the value in Angular in a dynamic way

My template needs to display the text 'Passed' only if item.name === 'michael' is not true. The component receives data in an array called courses[] from its parent. There are two interfaces, Courses and Teachers, where each course ID h ...

Configuring Nginx with letsencrypt taking longer than expected

My Nginx setup with letsencrypt is running slow, taking 404.8ms for the SSL segment. I'm wondering if there's a way to reconfigure Nginx to reduce this time, or if I should consider getting a CA that is closer to my server, or even switching to a ...

Getting a particular value from an array in Firestore: A step-by-step guide

When I retrieve specific data as an array from firestore, the value appears in the console.log() but I am unable to retrieve the specific data from the array itself. Here is my event.ts: import { Event } from '../../models/event'; invitedEvent ...

I am attempting to fetch data from an API and display it on the screen, yet I am encountering an issue where only the latest data from the API response is being rendered

HotelPage.tsx export interface Hotel { id: string; name: string; address1: string; address2: string; starRating: number; images: string[]; longDescription: string; } export interface Room { id: string; name: string; longDescription: st ...

Angular HTML Component Refactor causes compatibility issues with BS4 classes

Currently, I am working on Angular components and I have a specific section that I would like to refactor into a separate component for reusability. Initially, when the HTML block with only Bootstrap 4 classes is placed in the parent component, the user in ...

Troubleshooting Angular 6: Issues with Route Guards not functioning as expected

Striving to enhance frontend security by restricting access to specific IDs. The goal is to redirect anyone trying to access routes other than /login/:id to a page-not-found error message if not already logged in, but encountering some issues. Below are t ...

Struggling to launch on Vercel and encountering the error message, """is not allowed by Access-Control-Allow-Origin. Status code: 204""

Greetings! I trust you are doing well. Currently, I am engrossed in developing a full-stack application. The app runs smoothly on localhost without any issues. However, upon deploying both the server and front end on Vercel, a snag arose when attempting to ...

Encountering an error in Express while attempting to upload an image due to the inability to read the property 'file' of undefined

I am currently learning Express framework. I encountered an error while trying to upload an image using Express. The error message I received is "Cannot read property 'file' of undefined." Below are the code snippets that I am using, and I&apo ...

Angular2 Service Failing to Return Expected Value

It's frustrating that my services are not functioning properly. Despite spending the last two days scouring Stack Overflow for solutions, I haven't been able to find a solution that matches my specific issue. Here is a snippet of my Service.ts c ...

Performing an HTTP request to itself in NodeJS/ExpressJS

Currently coding an NPM module that requires making an HTTP request to itself, which is the running web server. Here's an example: let url = "http://127.0.0.1:" + (process.env.PORT || 3000) + path; request(url, function(error, response, body){ ... ...

Encountered an error while trying to npm install due to an invalid

I'm currently following a tutorial on this website to learn how to implement oauth2 in Node.js. Here is the content of my package.json file: { "name": "my-application", "version": "0.0.1", "private": true, "scripts": { "start": "coffee - ...

Obtaining the count of a specific column in Angular 6 by grouping objects based on the same value in an array

In TypeScript, I have an array of objects and I am using a foreach loop. The array contains 2 columns with a progress value of 100, while the rest have values less than 100. My goal is to calculate the count of columns with a progress value of 100, which ...

Guide to enclosing values in % % placeholders using the MySQL module in Node.js?

Can queries like this be written using the mysql module in Node.js? select * from table_name where name like "%value%"; In Node.js, you can utilize the ? placeholder to insert values into SQL queries. However, the code below does not yield the desired re ...

Managing Errors in Express JS

Currently, I am working on developing a REST API using Express JS. My goal is to incorporate error handling for various scenarios such as route not found, data not found, and validation errors. I am implementing an async await structure and require guidanc ...

The React Next app is experiencing issues that are possibly related to updates within a hook

After spending the last hour frustrated and confused, I can't seem to figure out why my code is only displaying the loading spinner but never updates to show the actual data. Even though I can see the data printed in the console, indicating that the d ...

Display an image on an HTML page based on the TypeScript data in an Ionic Angular application

After retrieving user profile data from the database and storing it in an observable, I am able to access properties such as profileData.username, profileData.msgnumber, and more. When profileData.avatar returns the name of the avatar the user is using, I ...