기능 순서
- 사용자는 프로필/정보수정 페이지에서 버튼을 통해 비밀번호를 변경할 수 있다.
- 현재 비밀번호와 변경을 원하는 비밀번호를 입력하고 Submit 버튼을 통해 비밀번호를 변경할 수 있다.
Route
import express from 'express';
// Controller
import {
resetPassword,
} from '../controllers/userController';
// Middleware
import { verifyTokenMiddleware } from '../middlewares/verifyToken';
const router = express.Router();
router.post('/reset-password', verifyTokenMiddleware, resetPassword);
export default router;
Controller
import { Request, Response } from 'express';
import { handleControllerError } from "../utils/error";
import { responseSuccess } from "../utils/response";
import {
resetPassword as resetPasswordService,
} from '../services/userService';
// 사용자 비밀번호 변경
// @ route patch /users/reset-password
// @ header Authorization Bearer token
export const resetPassword = async (req: Request, res: Response) => {
try {
const { oldPassword, newPassword } = req.body;
await resetPasswordService({userId: req.body.userId, oldPassword, newPassword});
responseSuccess(res, null, 'Password reset successfully', 200);
} catch (error) {
handleControllerError({res, error, message: 'Failed to reset password', statusCode: 400});
}
}
- 현재 로그인한 사용자의 정보는 Token을 통해 id만을 추출할 수 있음
- oldPassword, newPassword를 body로 입력 받아 Service로 전달
Service
import { Database } from '../db/index';
import { UserEntity } from '../db/entities/userEntity';
import { UserTokenEntity } from '../db/entities/userTokenEntity';
import { handleError } from '../utils/error';
import { hashPassword, comparePassword } from '../utils/bcrypt';
import { generateToken } from '../utils/jwtConfig';
import { deleteUserProfile } from '../utils/fs';
const userRepository = Database.getRepository(UserEntity);
const userTokenRepository = Database.getRepository(UserTokenEntity);
// 사용자 비밀번호 수정 함수
interface ResetPasswordProps {
userId: number;
oldPassword: string;
newPassword: string;
}
export const resetPassword = async (resetProps: ResetPasswordProps): Promise<void> => {
try {
const findUser = await userRepository.findOne({
where: { id: resetProps.userId }
});
if (!findUser) {
throw new Error('User not found');
}
// check copmare password
if (!comparePassword({password: resetProps.oldPassword, hashedPassword: findUser.password})) {
throw new Error('Password is incorrect');
}
// hash new password
const hashedPassword = hashPassword({password: resetProps.newPassword});
// update password
findUser.password = hashedPassword;
await userRepository.save(findUser);
return
} catch (error) {
handleError({error, message: 'Failed to reset password'});
}
}
- props로 받은 id를 통해 사용자가 존재하는 지 조회
- 현재 비밀번호라고 입력한 oldPassword가 일치하는 지 확인
- 일치하는 비밀번호라면 newPassword를 암호화하여 DB에 다시 저장
Request
{ // 현재 비밀번호가 틀렸을 시에
"message": "Failed to reset password",
"error": "Password is incorrect"
}
{ // 비밀번호 수정 성공시에
"message": "Password reset successfully",
"data": null
}