skip to Main Content

I have a setup of passport authentication on my express, node project. However when I’m accessing the req.user, I’m getting an error Property 'id' does not exist on type 'User'.ts(2339).
Here is my code

employee.controller.ts

import { Request, Response } from 'express';


    export const createEmployee = async (req:Request, res: Response) => {
    const currentUser = req.user.id
    return responseSuccess(res, {newUser:req.body,user: currentUser});
  };

passport.ts

import passportJWT from "passport-jwt";
import jwt from "jsonwebtoken";
import env from "../../config/env";
import Employee from "../models/employee.model";
import { PassportStatic } from 'passport';

const { ExtractJwt } = passportJWT;
const JwtStrategy = passportJWT.Strategy;

export function passportConfiguration(passport:PassportStatic) {
    const opts: passportJWT.StrategyOptions = {
        secretOrKey: env.jwtSecret,
        jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Bearer'),
    };

  passport.use(
    new JwtStrategy(opts, async (jwtPayload, cb) => {
      const employee = await Employee.findOne({ _id: jwtPayload.id }).select('-password -otpSecret').exec();
     
      if (employee) {
        cb(null, employee);
      } else {
        cb(new Error("Something wrong in token"), false);
      }
    })
  );
}

export function generateToken(employee:any) {
  return jwt.sign({ id: employee._id, email: employee.email }, env.jwtSecret, {
    expiresIn: env.jwtExpiresIn,
  });
}

Authentication.ts

import passport from "passport";
import UnauthorizedError from "../common/http-errors/UnauthorizedError";
import InternalServerError from "../common/http-errors/InternalServerError";
import messages from "../common/messages";

export default async (req, res, next) => {
  passport.authenticate("jwt", {}, (error, user, info) => {
    if (error) {
      return next(new InternalServerError());
    }

    if (user) {
      req.user = user
      return next();
    }
    return next(new UnauthorizedError(messages.auth.invalidToken));
  })(req, res, next);
};

What I tried is

  • When I tried to remove the Request on req:Request the error is gone. But it’s standard to put the Type in the req param.
  • List item const currentUser = req.user?.id still error persist

I’m not sure if this is tsconfig issue. Here is my tsconfig.json

{
  "files": ["src/index.ts", "config/env.ts"],
  "compilerOptions": {
      /* Basic Options */
     
      "skipLibCheck": true,
      
      "resolveJsonModule": true,
      "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
      "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
      "lib": ["es2015", "es2017"] /* Specify library files to be included in the compilation. */,
      "allowJs": true /* Allow javascript files to be compiled. */,
      "checkJs": true /* Report errors in .js files. */,
      "sourceMap": true /* Generates corresponding '.map' file. */,
      "outDir": "./dist" /* Redirect output structure to the directory. */,
      "typeRoots": ["src/typings", "./node_modules/@types"],
      "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */,
      "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
      "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
      "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    
  },
  "include": ["server/typings/*.ts", "server/typings/customer.d.ts"]
}

Sorry for adding the image. Just to show that the id is underlined error.
enter image description here

I’m stuck figuring out why.

2

Answers


  1. You’re using the type definition of Request from express module, which has no user attribute but only those found here. You have to write your own type definition or tell TS that it is there in some other way.

    Login or Signup to reply.
  2. You could create your own custom interface extends Express Request type to have your own type check

    import { Request } from "express";
    
    export interface AuthenticationRequest extends Request {
        User?: // define your type
    }
    
    export const createEmployee = async (req:AuthenticationRequest, res: Response) => {
        const currentUser = req.user.id
        return responseSuccess(res, {newUser:req.body,user: currentUser});
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search