fix user edit profile service

master
aliMohtarami 1 month ago
parent 61ac8246ab
commit 132dfacd5a
  1. 4
      src/users/dto/create-user.dto.ts
  2. 9
      src/users/dto/update-user.dto.ts
  3. 10
      src/users/users.controller.ts
  4. 58
      src/users/users.service.ts

@ -8,6 +8,10 @@ export class CreateUserDto {
@IsNotEmpty({ message: "Password is required" }) @IsNotEmpty({ message: "Password is required" })
password: string; password: string;
@IsString()
@IsNotEmpty({ message: "Password is required" })
role: string;
@IsString() @IsString()
@IsNotEmpty({ message: "First name is required" }) @IsNotEmpty({ message: "First name is required" })
firstName: string; firstName: string;

@ -1,6 +1,7 @@
import { IsOptional, IsString, IsEmail, IsEnum } from 'class-validator'; import { IsOptional, IsString, IsEmail, IsEnum } from 'class-validator';
import {Gender } from '../entities/user.entity'; import {Gender } from '../entities/user.entity';
import { Exclude } from 'class-transformer';
export class UpdateUserDto { export class UpdateUserDto {
@IsOptional() @IsOptional()
@ -15,6 +16,10 @@ export class UpdateUserDto {
@IsString() @IsString()
password?: string; password?: string;
@IsOptional()
@IsString()
role?: string;
@IsOptional() @IsOptional()
@IsString() @IsString()
firstName?: string; firstName?: string;
@ -30,4 +35,8 @@ export class UpdateUserDto {
@IsOptional() @IsOptional()
@IsEnum(Gender) @IsEnum(Gender)
gender?: Gender; gender?: Gender;
@Exclude()
@IsOptional()
refreshToken?: string;
} }

@ -6,18 +6,19 @@ import { LoginUserDto } from "./dto/login-user.dto";
import { JwtAuthGuard } from "src/guard/auth.guard"; import { JwtAuthGuard } from "src/guard/auth.guard";
import { UpdateUserDto } from "./dto/update-user.dto"; import { UpdateUserDto } from "./dto/update-user.dto";
import { RoleGuard } from "src/guard/role.guard"; import { RoleGuard } from "src/guard/role.guard";
import { plainToInstance } from "class-transformer";
@Controller("user") @Controller("user")
export class UsersController { export class UsersController {
constructor(private readonly usersService: UsersService) {} constructor(private readonly usersService: UsersService) {}
//register as user //register as user
@Post("register") @Post("register")
async register(@Body() createUserDto: CreateUserDto): Promise<{ message }> { async register(@Body() createUserDto: CreateUserDto) {
return this.usersService.register(createUserDto); return this.usersService.register(createUserDto);
} }
//login as user //login as user
@Post("login") @Post("login")
async login(@Body() loginUserDto: LoginUserDto): Promise<{ accessToken; refreshToken }> { async login(@Body() loginUserDto: LoginUserDto) {
return this.usersService.login(loginUserDto); return this.usersService.login(loginUserDto);
} }
//get access token //get access token
@ -44,7 +45,8 @@ export class UsersController {
@Put() @Put()
async editProfile(@Request() req, @Body() updateUserDto: UpdateUserDto) { async editProfile(@Request() req, @Body() updateUserDto: UpdateUserDto) {
const userId = req.user.id; const userId = req.user.id;
return this.usersService.editProfile(userId, updateUserDto); const { refreshToken, ...sanitizedDto } = updateUserDto;
return this.usersService.editProfile(userId, sanitizedDto);
} }
/////////////////////////////////////admin access endpoints///////////////////////////////////////////////////////// /////////////////////////////////////admin access endpoints/////////////////////////////////////////////////////////
//get users list (admin) //get users list (admin)
@ -56,7 +58,7 @@ export class UsersController {
// get a specific user info (admin) // get a specific user info (admin)
@UseGuards(RoleGuard) @UseGuards(RoleGuard)
@Get("users/:id") @Get("users/:id")
async findSpecificUserInfoByUser(@Param("id") id): Promise<User> { async findSpecificUserInfoByUser(@Param("id") id) {
return this.usersService.findSpecificUserInfoByUser(id); return this.usersService.findSpecificUserInfoByUser(id);
} }
// delete a specific user (admin) // delete a specific user (admin)

@ -7,6 +7,7 @@ import { ConfigService } from "@nestjs/config";
import { CreateUserDto } from "./dto/create-user.dto"; import { CreateUserDto } from "./dto/create-user.dto";
import { LoginUserDto } from "./dto/login-user.dto"; import { LoginUserDto } from "./dto/login-user.dto";
import { UpdateUserDto } from "./dto/update-user.dto"; import { UpdateUserDto } from "./dto/update-user.dto";
import e from "express";
@Injectable() @Injectable()
export class UsersService { export class UsersService {
@ -17,7 +18,7 @@ export class UsersService {
) {} ) {}
// Register method // Register method
async register(createUserDto: CreateUserDto): Promise<{ message: string }> { async register(createUserDto: CreateUserDto){
try { try {
createUserDto.password = await bcrypt.hash(createUserDto.password, parseInt(process.env.BCRYPT_SALT_ROUNDS || "10", 10)); createUserDto.password = await bcrypt.hash(createUserDto.password, parseInt(process.env.BCRYPT_SALT_ROUNDS || "10", 10));
@ -69,7 +70,7 @@ export class UsersService {
} }
} }
// Login method // Login method
async login(loginUserDto: LoginUserDto): Promise<{ accessToken: string , refreshToken:string}> { async login(loginUserDto: LoginUserDto){
try { try {
const user = await this.userModel.findOne({ const user = await this.userModel.findOne({
where: { email: loginUserDto.email, username:loginUserDto.username }, where: { email: loginUserDto.email, username:loginUserDto.username },
@ -114,7 +115,7 @@ export class UsersService {
} }
} }
// getting access token // getting access token
async newAccessToken(refreshToken: string) { async newAccessToken(refreshToken: string){
if (!refreshToken) { if (!refreshToken) {
throw new HttpException("Refresh token is required.", HttpStatus.BAD_REQUEST); throw new HttpException("Refresh token is required.", HttpStatus.BAD_REQUEST);
} }
@ -146,7 +147,7 @@ export class UsersService {
return { accessToken }; return { accessToken };
} }
//logout (delete refresh token from database) //logout (delete refresh token from database)
async logout(userId: number): Promise<{ message: string }> { async logout(userId: number){
if (!userId) { if (!userId) {
throw new HttpException("User ID is required.", HttpStatus.BAD_REQUEST); throw new HttpException("User ID is required.", HttpStatus.BAD_REQUEST);
} }
@ -165,7 +166,7 @@ export class UsersService {
} }
} }
//get information user method //get information user method
async getProfile(userId: number): Promise<User> { async getProfile(userId: number){
try { try {
const user = await this.userModel.findOne({ const user = await this.userModel.findOne({
where: { id: userId }, where: { id: userId },
@ -186,19 +187,56 @@ export class UsersService {
if (!user) { if (!user) {
throw new NotFoundException("User not found."); throw new NotFoundException("User not found.");
} }
if (updateUserDto.password) {
updateUserDto.password = await bcrypt.hash(updateUserDto.password, 10); const { refreshToken, ...allowedUpdates } = updateUserDto;
if (allowedUpdates.username) {
const usernameExists = await this.userModel.findOne({
where: { username: allowedUpdates.username },
});
if (usernameExists && usernameExists.id !== userId) {
throw new BadRequestException("Username is already in use.");
}
}
if (allowedUpdates.phoneNumber) {
const phoneNumberExists = await this.userModel.findOne({
where: { phoneNumber: allowedUpdates.phoneNumber },
});
if (phoneNumberExists && phoneNumberExists.id !== userId) {
throw new BadRequestException("Phone number is already in use.");
}
}
if (allowedUpdates.email) {
const emailExists = await this.userModel.findOne({
where: { email: allowedUpdates.email },
});
if (emailExists && emailExists.id !== userId) {
throw new BadRequestException("Email is already in use.");
}
}
if (allowedUpdates.password) {
allowedUpdates.password = await bcrypt.hash(allowedUpdates.password, 10);
} }
await user.update(updateUserDto);
await user.update(allowedUpdates);
user = await this.userModel.findOne({ user = await this.userModel.findOne({
where: { id: userId }, where: { id: userId },
attributes: { exclude: ["password"] }, attributes: { exclude: ["password", "refreshToken"] },
}); });
return { message: "User account updated successfully.", user }; return { message: "User account updated successfully.", user };
} catch (error) { } catch (error) {
console.error(error)
if (error instanceof HttpException) {
throw error;
}
throw new HttpException("An unexpected error occurred. Please try again later.", HttpStatus.INTERNAL_SERVER_ERROR); throw new HttpException("An unexpected error occurred. Please try again later.", HttpStatus.INTERNAL_SERVER_ERROR);
} }
} }
//get users list //get users list
async findAll(): Promise<User[]> { async findAll(): Promise<User[]> {
try { try {

Loading…
Cancel
Save