Reputation: 1
I am trying to convert a user authentication API written in JavaScript to TypeScript. My auth middleware adds the 'user object' to 'req object' if user is authenticated, now when I try to access it in my Controllers, TypeScript gives error 'Property user does not exist on type Request'
I tried -
declare global {
namespace Express {
export interface Request {
user?: any;
}
}
}
But if I give 'any' as type, then what will be meaning of Defining Types that I am using TypeScript for...
Router -
import express, { Router, Request, Response } from "express";
const router: Router = express.Router();
const userController = require("./../controllers/userController");
const auth = require("./../middleware/auth");
router.patch("/change-password", auth, userController.changePassword);
Auth Middleware -
const verifyJWT = async (req: Request, res: Response, next: NextFunction) => {
try {
const accessToken = req.headers["x-access-token"];
if (!accessToken)
return res.status(401).json({ error: `Token is required.` });
const decodedToken = await jwt.verify(
accessToken,
config.ACCESS_TOKEN_KEY
);
if (!decodedToken)
return res.status(403).json({ error: `Invalid Token.` });
const user = await User.findOne({ _id: decodedToken._id, accessToken });
if (!user) return res.status(400).json({ error: `No user found.` });
req.user = user;
req.accessToken = accessToken;
next();
} catch (err: any) {
console.log("--MSG--" + err.message + "--NAME--" + err.name);
if (err.name === "TokenExpiredError") {
return res.status(401).json({
error: "invalid_token",
message: "The access token expired",
});
}
res.status(500).json({
error: "authentication_error",
message: "Error while authenticating",
});
}
};
module.exports = verifyJWT;
Controller -
const changePassword: Function = async (req: Request, res: Response) => {
try {
// The auth middleware sets req.user with the user's document so I can use user document to Query the database.
const { currentPass, newPass, confirmPass } = req.body;
if (!currentPass || !newPass || !confirmPass) {
return res
.status(400)
.json({ error: `Please fill all the required fields` });
}
if (newPass !== confirmPass) {
return res.status(400).json({
error: `New password doesn't match confirmation password`,
});
}
if (req.user) {
if (await bcrypt.compare(currentPass, req.user.password)) {
req.user.password = newPass;
await req.user.save();
return res
.status(200)
.json({ result: 1, message: resMsgs.success.s4 });
} else {
return res.status(400).json({ error: `Wrong password` });
}
}
} catch (err: any) {
console.log(err.message);
res.status(500).json({ error: `Something went wrong` });
}
};
Upvotes: 0
Views: 826
Reputation: 2946
In typescript you can declare what are the exports of a node module.
If the node module does not come with it's own types or if you want to modify it's types you can simply create additional declarations, like this:
declare module 'express'
{
export interface Request
{
// if you're using mongoose
user?: HydratedDocument<IUser>
// if you're not using mongoose
user?: IUser
}
}
export interface IUser
{
id: string
name: string
}
Upvotes: 1