#node.js #typescript #jwt #nodemailer
#node.js #typescript #jwt #nodemailer
Вопрос:
У меня возникла проблема с моей функцией сброса пароля ( changepass
), и, вероятно, это небольшая ошибка в моем коде.
После обработки нового пароля через nodemailer и успешного входа в систему я пытаюсь реализовать следующую функциональность, позволяющую пользователю обновлять свой пароль.
Мое промежуточное программное обеспечение auth отлично работает во всех других функциях после входа пользователя в систему.
При входе в систему я отправляю старый и новый пароль в теле и новый токен в Bearer Token
поле. Удивительно, но я возвращаю статус 204, поскольку он проработал весь путь.
На терминале я продолжаю получать следующее:
const id = res.locals.userId; -> undefined;
No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies.
Функция определенно что-то делает, но она больше не может входить в систему ни со старым, ни с новым паролем, поэтому мне нужно снова запросить новый пароль через nodemailer.
Кто-нибудь знает, в чем моя ошибка?
Сброс пароля (где проблема):
async changepass(req: Request, res: Response) {
// Get ID from JWT
const id = res.locals.userId;
console.log(id)
// Get parameters from the body
const { oldPassword, newPassword } = req.body;
if (!(oldPassword amp;amp; newPassword)) {
res.status(400).send();
}
// Get user from the database
const userRepository = getRepository(User);
// let user = await userRepository.findOneOrFail(id);
let user = User as any;
try {
user = await userRepository.findOneOrFail(id);
} catch (id) {
res.status(401).send();
}
// Check if old password matches
if (!user.checkIfUnencryptedPasswordIsValid(oldPassword)) {
res.status(401).send();
return;
}
// Validate the model (Password length)
user.password = newPassword;
const errors = await validate(user);
if (errors.length > 0) {
res.status(400).send(errors);
return;
}
// Hash the new password and save
user.hashPassword();
userRepository.save(user);
res.status(204).send();
},
Вход пользователя:
async login(req: Request, res: Response) {
// Get user from database
const userRepository = getRepository(User);
const { email, password } = req.body;
// Check if useremail and password are set
if (!(email amp;amp; password)) {
console.error('Empty name or password!');
return res.status(400).send({
error: 'Empty name or password'
});
}
const user = await userRepository.findOne({ where: { email } });
if(!user) {
return res.sendStatus(401);
}
// Check if encrypted password match : checkIfUnenc... função vemm do model
if (!user.checkIfUnencryptedPasswordIsValid(password)) {
return res.status(401).send({
error: 'Cannot match encrypted password'
});
}
// Sing JWT, valid for 1 hour
const token = jwt.sign(
{ id: user.id, email: user.email }, //payload do token, informações do user
config.jwtSecret, //chave secreta que autoriza, ideal no .env
{ expiresIn: "1d" }
);
// Send the jwt in the response
res.json({
user,
token
});
},
Маршрут:
//change password route
routes.post('/users/changepass', checkJwt, UserController.changepass);
Промежуточное ПО аутентификации:
interface TokenPayload {
id: number;
iat: string;
exp: string;
}
export default function checkJwt(req: Request, res: Response, next: NextFunction) {
const { authorization } = req.headers;
// console.log(authorization)
if(!authorization) {
return res.sendStatus(401)
}
const token = authorization.replace("Bearer", "").trim(); //apenas remover a palavra "Bearer" e espaço
try {
const data = jwt.verify(token, config.jwtSecret)
//console.log(data) -> data traz no log o id, iat, exp, então tenho que tipar o data com interface
const { id } = data as TokenPayload;
req.userId = id;
console.log(id)
} catch {
return res.sendStatus(401);
}
next();
}