AnhLedger commited on
Commit
c0f9d1c
1 Parent(s): 37909eb

update user info, create validate service

Browse files
backend/src/modules/authentication/authentication.module.ts CHANGED
@@ -7,6 +7,7 @@ import { AuthenticationGuard } from './authentication.guard.js';
7
  import { APP_GUARD } from '@nestjs/core';
8
  import { ConfigModule, ConfigService } from '@nestjs/config';
9
  import { RolesGuard } from './authorization/roles.guard.js';
 
10
  @Module({
11
  imports: [
12
  UserModule,
@@ -28,7 +29,8 @@ import { RolesGuard } from './authorization/roles.guard.js';
28
  {
29
  provide: APP_GUARD,
30
  useClass: RolesGuard,
31
- }
 
32
  ],
33
  controllers: [AuthenticationController],
34
  exports: [AuthenticationService],
 
7
  import { APP_GUARD } from '@nestjs/core';
8
  import { ConfigModule, ConfigService } from '@nestjs/config';
9
  import { RolesGuard } from './authorization/roles.guard.js';
10
+ import { ValidateService } from '../../validate/validate.service.js';
11
  @Module({
12
  imports: [
13
  UserModule,
 
29
  {
30
  provide: APP_GUARD,
31
  useClass: RolesGuard,
32
+ },
33
+ ValidateService
34
  ],
35
  controllers: [AuthenticationController],
36
  exports: [AuthenticationService],
backend/src/modules/authentication/authentication.service.ts CHANGED
@@ -4,11 +4,13 @@ import * as bcrypt from 'bcrypt';
4
  import { JwtService } from '@nestjs/jwt';
5
  import { SignUpDto } from './dto/sign-up.dto.js';
6
  import { UserEntity } from '../../entities/user.entity.js';
 
7
  @Injectable()
8
  export class AuthenticationService {
9
  constructor(
10
  private usersService: UserService,
11
  private jwtService: JwtService,
 
12
  ) {}
13
 
14
  async signIn(
@@ -20,10 +22,12 @@ export class AuthenticationService {
20
  user = await this.usersService.findOneByField('email', username);
21
  else
22
  user = await this.usersService.findOneByField('phone_number', username);
23
- if (!user || (await !bcrypt.compare(pass, user.hash_password))) {
 
 
24
  throw new UnauthorizedException();
25
  }
26
- const payload = { sub: user.id, username: user.id, roles: user.role.role_name};
27
  return {
28
  access_token: await this.jwtService.signAsync(payload),
29
  };
@@ -39,8 +43,8 @@ export class AuthenticationService {
39
  password
40
  } = signUpDto
41
 
42
- await this.checkExistField('email', email);
43
- await this.checkExistField('phone_number', phone_number)
44
  const hash_password = await bcrypt.hash(password, 10)
45
 
46
  const user = await this.usersService.create({
 
4
  import { JwtService } from '@nestjs/jwt';
5
  import { SignUpDto } from './dto/sign-up.dto.js';
6
  import { UserEntity } from '../../entities/user.entity.js';
7
+ import { ValidateService } from '../../validate/validate.service.js';
8
  @Injectable()
9
  export class AuthenticationService {
10
  constructor(
11
  private usersService: UserService,
12
  private jwtService: JwtService,
13
+ private validatService: ValidateService
14
  ) {}
15
 
16
  async signIn(
 
22
  user = await this.usersService.findOneByField('email', username);
23
  else
24
  user = await this.usersService.findOneByField('phone_number', username);
25
+ const compare = await bcrypt.compare(pass, user.hash_password)
26
+ console.log(compare);
27
+ if (( !user || !compare )) {
28
  throw new UnauthorizedException();
29
  }
30
+ const payload = { sub: user.id, username: user.full_name, roles: user.role.role_name};
31
  return {
32
  access_token: await this.jwtService.signAsync(payload),
33
  };
 
43
  password
44
  } = signUpDto
45
 
46
+ await this.validatService.checkExistField('email', email);
47
+ await this.validatService.checkExistField('phone_number', phone_number)
48
  const hash_password = await bcrypt.hash(password, 10)
49
 
50
  const user = await this.usersService.create({
backend/src/modules/authentication/rbac-policy.ts DELETED
@@ -1,9 +0,0 @@
1
- import { RolesBuilder } from 'nest-access-control';
2
- import { Role } from './enums';
3
-
4
- export const RBAC_POLICY: RolesBuilder = new RolesBuilder();
5
-
6
- // prettier-ignore
7
- RBAC_POLICY
8
- .grant(Role.ADMIN)
9
- .read()
 
 
 
 
 
 
 
 
 
 
backend/src/modules/user/dto/update-user-dto.ts ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { IsEmail, IsMobilePhone, IsOptional, IsString } from "class-validator";
2
+ import { Column } from "typeorm";
3
+
4
+ export class UpdateUserDto{
5
+
6
+ @IsOptional()
7
+ avatar: string;
8
+
9
+ @IsOptional()
10
+ full_name: string;
11
+
12
+ @IsOptional()
13
+ @IsMobilePhone('vi-VN')
14
+ phone_number: string;
15
+
16
+ @IsOptional()
17
+ address: string;
18
+
19
+ @IsOptional()
20
+ @IsEmail()
21
+ email: string;
22
+
23
+ @IsOptional()
24
+ role_id: string;
25
+
26
+ @IsOptional()
27
+ hash_password: string;
28
+
29
+ @IsOptional()
30
+ is_valid: boolean;
31
+ }
backend/src/modules/user/user.controller.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { Controller, Get, Param } from '@nestjs/common';
2
  import { UserService } from './user.service.js';
3
  import { UserEntity } from 'src/entities/user.entity.js';
 
4
 
5
  @Controller('users')
6
  export class UsersController {
@@ -12,4 +13,11 @@ export class UsersController {
12
  ): Promise<UserEntity | undefined> {
13
  return this.usersService.findOne(username);
14
  }
 
 
 
 
 
 
 
15
  }
 
1
+ import { Body, Controller, Get, Param, Post, Request } from '@nestjs/common';
2
  import { UserService } from './user.service.js';
3
  import { UserEntity } from 'src/entities/user.entity.js';
4
+ import { UpdateUserDto } from './dto/update-user-dto.js';
5
 
6
  @Controller('users')
7
  export class UsersController {
 
13
  ): Promise<UserEntity | undefined> {
14
  return this.usersService.findOne(username);
15
  }
16
+
17
+ @Post('updateUser')
18
+ async updateUser(@Request() req){
19
+ const userId = req.user.sub;
20
+ const updateUserDto = req.body;
21
+ return this.usersService.updateUserById(userId, updateUserDto);
22
+ }
23
  }
backend/src/modules/user/user.module.ts CHANGED
@@ -1,8 +1,23 @@
1
  import { Module } from '@nestjs/common';
2
  import { UserService } from './user.service.js';
 
 
 
 
3
 
4
  @Module({
5
- providers: [UserService],
 
 
 
 
 
 
 
 
 
 
 
6
  exports: [UserService],
7
  })
8
  export class UserModule {}
 
1
  import { Module } from '@nestjs/common';
2
  import { UserService } from './user.service.js';
3
+ import { ValidateService } from '../../validate/validate.service.js';
4
+ import { UsersController } from './user.controller.js';
5
+ import { JwtModule } from '@nestjs/jwt';
6
+ import { ConfigModule, ConfigService } from '@nestjs/config';
7
 
8
  @Module({
9
+ imports: [
10
+ JwtModule.registerAsync({
11
+ imports: [ConfigModule], // Nhập ConfigModule để sử dụng ConfigService
12
+ useFactory: async (configService: ConfigService) => ({
13
+ secret: configService.get<string>('JWT_KEY'), // Lấy giá trị từ biến môi trường
14
+ signOptions: { expiresIn: '7d' }, // Thời gian hết hạn token
15
+ }),
16
+ inject: [ConfigService], // Inject ConfigService vào factory
17
+ }),
18
+ ],
19
+ controllers: [UsersController],
20
+ providers: [UserService, ValidateService],
21
  exports: [UserService],
22
  })
23
  export class UserModule {}
backend/src/modules/user/user.service.ts CHANGED
@@ -1,12 +1,19 @@
1
- import { Injectable } from '@nestjs/common';
2
  import { UserEntity } from '../../entities/user.entity.js';
3
  import { SignUpDto } from '../authentication/dto/sign-up.dto.js';
 
 
 
 
4
 
5
  export type User = any;
6
 
7
  @Injectable()
8
  export class UserService {
9
- constructor() {}
 
 
 
10
 
11
  async findOne(username: string): Promise<UserEntity | undefined> {
12
  return UserEntity.findOne({ where: { full_name: username } });
@@ -31,4 +38,31 @@ export class UserService {
31
  relations: ['role']
32
  });
33
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
 
1
+ import { Body, forwardRef, Inject, Injectable, NotFoundException } from '@nestjs/common';
2
  import { UserEntity } from '../../entities/user.entity.js';
3
  import { SignUpDto } from '../authentication/dto/sign-up.dto.js';
4
+ import { UpdateUserDto } from './dto/update-user-dto.js';
5
+ import { ValidateService } from '../../validate/validate.service.js';
6
+ import * as bcrypt from 'bcrypt';
7
+ import { JwtService } from '@nestjs/jwt';
8
 
9
  export type User = any;
10
 
11
  @Injectable()
12
  export class UserService {
13
+ constructor(
14
+ private validateService: ValidateService,
15
+ private jwtService: JwtService,
16
+ ) {}
17
 
18
  async findOne(username: string): Promise<UserEntity | undefined> {
19
  return UserEntity.findOne({ where: { full_name: username } });
 
38
  relations: ['role']
39
  });
40
  }
41
+
42
+ async updateUserById(userId: string, updateUserDto: UpdateUserDto){
43
+
44
+ await this.validateService.checkExistField('email', updateUserDto.email);
45
+ await this.validateService.checkExistField('phone_number', updateUserDto.phone_number);
46
+
47
+ const user = await UserEntity.findOne({
48
+ where: { id: userId },
49
+ relations: ['role']
50
+ });
51
+ if (!user) {
52
+ throw new NotFoundException(`User with ID ${userId} not found`);
53
+ }
54
+
55
+ Object.assign(user, updateUserDto);
56
+ if (updateUserDto.hash_password) {
57
+ const saltRounds = 10;
58
+ user.hash_password = await bcrypt.hash(updateUserDto.hash_password, saltRounds); // Mã hóa mật khẩu
59
+ }
60
+ await UserEntity.save(user);
61
+
62
+ const payload = { sub: user.id, username: user.full_name, roles: user.role.role_name };
63
+ const token = await this.jwtService.signAsync(payload)
64
+ return {
65
+ access_token: token
66
+ };
67
+ }
68
  }
backend/src/validate/validate.service.spec.ts ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+ import { ValidateService } from './validate.service';
3
+
4
+ describe('ValidateService', () => {
5
+ let service: ValidateService;
6
+
7
+ beforeEach(async () => {
8
+ const module: TestingModule = await Test.createTestingModule({
9
+ providers: [ValidateService],
10
+ }).compile();
11
+
12
+ service = module.get<ValidateService>(ValidateService);
13
+ });
14
+
15
+ it('should be defined', () => {
16
+ expect(service).toBeDefined();
17
+ });
18
+ });
backend/src/validate/validate.service.ts ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // validation.service.ts
2
+ import { Injectable, ConflictException } from '@nestjs/common';
3
+ import { UserEntity } from '../entities/user.entity.js';
4
+
5
+ @Injectable()
6
+ export class ValidateService {
7
+ constructor() {}
8
+
9
+ // Kiểm tra xem giá trị của một trường có tồn tại không
10
+ async checkExistField(fieldName: string, fieldValue: any): Promise<void> {
11
+ if (fieldValue === null || fieldValue === undefined) {
12
+ return; // Nếu giá trị null hoặc undefined, không cần kiểm tra
13
+ }
14
+
15
+ // Tìm trong database theo tên và giá trị của trường
16
+ const existingUser = await UserEntity.findOne({
17
+ where: { [fieldName]: fieldValue },
18
+ relations: ['role']
19
+ });
20
+
21
+ if (existingUser) {
22
+ throw new ConflictException(`${fieldName} is already taken`);
23
+ }
24
+ }
25
+ }