Enhance error handling in user module

master
nicekid1 1 month ago
parent 5d5c1c2eef
commit b26dff1fd4
  1. 17
      src/users/users.controller.ts
  2. 100
      src/users/users.service.ts

@ -1,4 +1,4 @@
import { Controller, Post, Body, UseGuards, Get, Request, Put, Param } from "@nestjs/common";
import { Controller, Post, Body, UseGuards, Get, Request, Put, Param, HttpException, HttpStatus, Delete } from "@nestjs/common";
import { UsersService } from "./users.service";
import { User } from "./entities/user.entity";
import { CreateUserDto } from "./dto/create-user.dto";
@ -17,13 +17,15 @@ export class UsersController {
}
//login as user
@Post("login")
async login(@Body() loginUserDto: LoginUserDto): Promise<{ accessToken; refreshToken }> {
async login(@Body() loginUserDto: LoginUserDto): Promise<{ accessToken }> {
return this.usersService.login(loginUserDto);
}
//get access token
@Post("new-token")
async newAccessToken(@Body("refreshToken") refreshToken: string) {
return this.usersService.newAccessToken(refreshToken);
@UseGuards(JwtAuthGuard)
@Get("new-token")
async newAccessToken(@Request() req) {
const userId = req.user.id;
return this.usersService.newAccessToken(userId);
}
//logout user
@UseGuards(JwtAuthGuard)
@ -61,8 +63,11 @@ export class UsersController {
}
//delete a specific user by admin
@UseGuards(RoleGuard)
@Get("users/delete/:id")
@Delete(":id?")
async deleteUser(@Param("id") id){
if (!id) {
throw new HttpException("User ID is required.", HttpStatus.BAD_REQUEST);
}
return this.usersService.deleteUser(id);
}
}

@ -17,17 +17,42 @@ export class UsersService {
) {}
// Register method
async register(createUserDto: CreateUserDto): Promise<{ message }> {
async register(createUserDto: CreateUserDto): Promise<{ message: string }> {
try {
createUserDto.password = await bcrypt.hash(createUserDto.password, parseInt(process.env.BCRYPT_SALT_ROUNDS || "10", 10));
const userExists = await this.userModel.findOne({
const emailExists = await this.userModel.findOne({
where: { email: createUserDto.email },
});
if (userExists) {
if (emailExists) {
throw new BadRequestException("Email is already registered.");
}
const user = await this.userModel.create(createUserDto);
return { message: "user registered successful" };
const phoneExists = await this.userModel.findOne({
where: { phoneNumber: createUserDto.phoneNumber },
});
if (phoneExists) {
throw new BadRequestException("Phone number is already registered.");
}
await this.userModel.create(createUserDto);
const user = await this.userModel.findOne({
where: { email: createUserDto.email },
});
const refreshToken = this.jwtService.sign(
{ id: user.id },
{
secret: this.configService.get<string>("JWT_REFRESH_SECRET"),
expiresIn: this.configService.get<string | number>("JWT_REFRESH_EXPIRES") || "7d",
},
);
await this.userModel.update(
{ refreshToken }, //
{ where: { id: user.id } },
);
return { message: "User registered successfully." };
} catch (error) {
if (error instanceof HttpException) {
throw error;
@ -36,7 +61,7 @@ export class UsersService {
}
}
// Login method
async login(loginUserDto: LoginUserDto): Promise<{ accessToken: string; refreshToken: string }> {
async login(loginUserDto: LoginUserDto): Promise<{ accessToken: string }> {
try {
const user = await this.userModel.findOne({
where: { email: loginUserDto.email },
@ -72,7 +97,7 @@ export class UsersService {
{ where: { id: user.id } },
);
return { accessToken: accessToken, refreshToken: refreshToken };
return { accessToken: accessToken };
} catch (error) {
if (error instanceof HttpException) {
throw error;
@ -81,23 +106,21 @@ export class UsersService {
}
}
// getting access token
async newAccessToken(refreshToken: string) {
if (!refreshToken) {
throw new HttpException({ message: "Refresh token is required." }, HttpStatus.BAD_REQUEST);
async newAccessToken(userId: number) {
const user = await this.userModel.findOne({ where: { id: userId } });
if (!user || !user.refreshToken) {
throw new HttpException("Refresh token is required.", HttpStatus.BAD_REQUEST);
}
let decoded;
try {
decoded = this.jwtService.verify(refreshToken, { secret: process.env.JWT_REFRESH_SECRET });
decoded = this.jwtService.verify(user.refreshToken, { secret: process.env.JWT_REFRESH_SECRET });
} catch (error) {
throw new HttpException({ message: "Invalid or expired token." }, HttpStatus.UNAUTHORIZED);
throw new HttpException("Invalid or expired token.", HttpStatus.UNAUTHORIZED);
}
const user = await this.userModel.findOne({
where: { id: decoded.id },
});
if (!user) {
throw new HttpException({ message: "User not found." }, HttpStatus.NOT_FOUND);
if (user.id !== decoded.id) {
throw new HttpException("User ID mismatch.", HttpStatus.FORBIDDEN);
}
const accessToken = this.jwtService.sign(
@ -111,15 +134,23 @@ export class UsersService {
return { accessToken };
}
//logout (delete refresh token from database)
async logout(userId: number) {
const user = await this.userModel.findOne({
where: { id: userId },
});
if (!user) {
throw new HttpException("User not found.", HttpStatus.NOT_FOUND);
async logout(userId: number): Promise<{ message: string }> {
if (!userId) {
throw new HttpException("User ID is required.", HttpStatus.BAD_REQUEST);
}
try {
const user = await this.userModel.findOne({ where: { id: userId } });
if (!user) {
throw new HttpException("User not found.", HttpStatus.NOT_FOUND);
}
await this.userModel.update({ refreshToken: null }, { where: { id: userId } });
return { message: "Logout is successful." };
} catch (error) {
throw new HttpException("An error occurred while logging out.", HttpStatus.INTERNAL_SERVER_ERROR);
}
await this.userModel.update({ refreshToken: null }, { where: { id: userId } });
return { message: "logout is successful" };
}
//get information user method
async getProfile(userId: number): Promise<User> {
@ -177,16 +208,23 @@ export class UsersService {
}
}
//delete a specific user by admin
async deleteUser(userId: number) {
async deleteUser(userId: number): Promise<{ message: string }> {
const user = await this.userModel.findOne({
where: { id: userId },
});
if (!user) {
throw new HttpException("User not found.", HttpStatus.NOT_FOUND);
throw new HttpException("User not found!.", HttpStatus.NOT_FOUND);
}
try {
const deletedCount = await this.userModel.destroy({ where: { id: userId } });
if (deletedCount === 0) {
throw new HttpException("User not found.", HttpStatus.NOT_FOUND);
}
return { message: "User deleted successfully." };
} catch (error) {
throw new HttpException("An error occurred while deleting the user.", HttpStatus.INTERNAL_SERVER_ERROR);
}
await this.userModel.destroy({
where: { id: userId },
});
return { message: "user deleted successful" };
}
}

Loading…
Cancel
Save