feat: added user role
This commit is contained in:
@@ -9,10 +9,11 @@ import { OTP } from './entities/otp.entity';
|
|||||||
import { OtpRepository } from './repositories/otp.repository';
|
import { OtpRepository } from './repositories/otp.repository';
|
||||||
import { UsersModule } from 'src/users/users.module';
|
import { UsersModule } from 'src/users/users.module';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { UserRole } from 'src/users/entities/user-role.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([User, OTP]),
|
TypeOrmModule.forFeature([OTP]),
|
||||||
JwtModule.register({}),
|
JwtModule.register({}),
|
||||||
UtilsModule,
|
UtilsModule,
|
||||||
UsersModule,
|
UsersModule,
|
||||||
|
|||||||
@@ -10,4 +10,8 @@ export enum OTPMessages {
|
|||||||
OTP_EXPIRED = 'این کد منسوخ شده است لطفا دوباره درخواست بدهید!',
|
OTP_EXPIRED = 'این کد منسوخ شده است لطفا دوباره درخواست بدهید!',
|
||||||
OTP_TOO_MANY_TRIES = 'تعداد تلاش ها بیش از حد مجاز است لطفا دوباره درخواست کد بدهید!',
|
OTP_TOO_MANY_TRIES = 'تعداد تلاش ها بیش از حد مجاز است لطفا دوباره درخواست کد بدهید!',
|
||||||
OTP_INVALID = 'کد وارد شده نا معتبر است!'
|
OTP_INVALID = 'کد وارد شده نا معتبر است!'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum UserRoleMessages {
|
||||||
|
USER_ROLE_ALREADY_EXISTS = 'نقش مورد نظر برای کاربر مد نظر وجود دارد!'
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { IsEnum } from "class-validator";
|
||||||
|
import { RoleType } from "../enums/user-role.enum";
|
||||||
|
|
||||||
|
export class CreateUserRoleDto {
|
||||||
|
@ApiProperty({
|
||||||
|
enum: RoleType,
|
||||||
|
example: RoleType.NORMAL_USER
|
||||||
|
})
|
||||||
|
@IsEnum(RoleType)
|
||||||
|
role: RoleType;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { BaseEntity } from "src/common/entities/base.entity";
|
||||||
|
import { Column, Entity, JoinColumn, ManyToOne, Unique } from "typeorm";
|
||||||
|
import { RoleType } from "../enums/user-role.enum";
|
||||||
|
import { User } from "./user.entity";
|
||||||
|
|
||||||
|
@Entity('user_roles')
|
||||||
|
@Unique(['user', 'role'])
|
||||||
|
export class UserRole extends BaseEntity {
|
||||||
|
@Column({
|
||||||
|
type: 'enum',
|
||||||
|
enum: RoleType,
|
||||||
|
default: RoleType.NORMAL_USER
|
||||||
|
})
|
||||||
|
role: RoleType;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, (user) => user.roles, {
|
||||||
|
nullable: false,
|
||||||
|
onDelete: 'CASCADE'
|
||||||
|
})
|
||||||
|
@JoinColumn({ name: 'userId' })
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
@@ -1,31 +1,36 @@
|
|||||||
import { Entity, Column } from "typeorm";
|
import { Entity, Column, ManyToMany, JoinTable, OneToMany } from 'typeorm';
|
||||||
import { BaseEntity } from "src/common/entities/base.entity";
|
import { BaseEntity } from 'src/common/entities/base.entity';
|
||||||
import { Exclude } from "class-transformer";
|
import { Exclude } from 'class-transformer';
|
||||||
|
import { UserRole } from './user-role.entity';
|
||||||
|
|
||||||
@Entity('users')
|
@Entity('users')
|
||||||
export class User extends BaseEntity {
|
export class User extends BaseEntity {
|
||||||
@Column({type: 'varchar', length: 20})
|
@Column({ type: 'varchar', length: 20 })
|
||||||
firstName: string;
|
firstName: string;
|
||||||
|
|
||||||
@Column({type: 'varchar', length: 20})
|
@Column({ type: 'varchar', length: 20 })
|
||||||
lastName: string;
|
lastName: string;
|
||||||
|
|
||||||
@Column({unique: true, type: 'varchar', length: 100})
|
@Column({ unique: true, type: 'varchar', length: 100 })
|
||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
@Column({unique: true, type: 'varchar', length: 11})
|
@Column({ unique: true, type: 'varchar', length: 11 })
|
||||||
phone: string;
|
phone: string;
|
||||||
|
|
||||||
@Column({
|
@Column({})
|
||||||
})
|
@Exclude()
|
||||||
@Exclude()
|
password: string;
|
||||||
password: string;
|
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
name: 'refresh_token',
|
name: 'refresh_token',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
select: false
|
select: false,
|
||||||
})
|
})
|
||||||
@Exclude()
|
@Exclude()
|
||||||
refreshToken: string;
|
refreshToken: string;
|
||||||
}
|
|
||||||
|
@OneToMany(() => UserRole, (userRole) => userRole.user, {
|
||||||
|
cascade: true
|
||||||
|
})
|
||||||
|
roles: UserRole[];
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export enum RoleType {
|
||||||
|
NORMAL_USER = 'normal_user',
|
||||||
|
ADMIN = 'admin',
|
||||||
|
EXPERT = 'expert'
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { UserRole } from '../entities/user-role.entity';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserRoleRepository extends Repository<UserRole> {
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(UserRole) userRoleRepository: Repository<UserRole>,
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
userRoleRepository.target,
|
||||||
|
userRoleRepository.manager,
|
||||||
|
userRoleRepository.queryRunner,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Repository } from "typeorm";
|
import { Repository } from "typeorm";
|
||||||
import { User } from "./entities/user.entity";
|
import { User } from "../entities/user.entity";
|
||||||
import { InjectRepository } from "@nestjs/typeorm";
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
import { Injectable } from "@nestjs/common";
|
import { Injectable } from "@nestjs/common";
|
||||||
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Body, Controller, Get, Post } from '@nestjs/common';
|
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
|
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
|
||||||
import { CreateUserDto } from './DTO/create-user.dto';
|
import { CreateUserDto } from './DTO/create-user.dto';
|
||||||
import { User } from './entities/user.entity';
|
import { User } from './entities/user.entity';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
import { CreateUserRoleDto } from './DTO/create-user-role.dto';
|
||||||
|
|
||||||
@Controller('users')
|
@Controller('users')
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
@@ -18,4 +19,12 @@ export class UsersController {
|
|||||||
signupUser(@Body() body: CreateUserDto): Promise<User> {
|
signupUser(@Body() body: CreateUserDto): Promise<User> {
|
||||||
return this.userService.createUser(body);
|
return this.userService.createUser(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post(':userId/roles')
|
||||||
|
createRole(
|
||||||
|
@Param('userId') userId: string,
|
||||||
|
@Body() userRoleDto: CreateUserRoleDto
|
||||||
|
) {
|
||||||
|
return this.userService.createUserRole(userId, userRoleDto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { UsersController } from './users.controller';
|
import { UsersController } from './users.controller';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
import { UserRepository } from './user.repository';
|
import { UserRepository } from './repositories/user.repository';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { User } from './entities/user.entity';
|
import { User } from './entities/user.entity';
|
||||||
|
import { UserRoleRepository } from './repositories/user-role.repository';
|
||||||
|
import { UserRole } from './entities/user-role.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [TypeOrmModule.forFeature([User, UserRole])],
|
||||||
TypeOrmModule.forFeature([User])
|
|
||||||
],
|
|
||||||
controllers: [UsersController],
|
controllers: [UsersController],
|
||||||
providers: [UsersService, UserRepository],
|
providers: [UsersService, UserRepository, UserRoleRepository],
|
||||||
exports: [UsersService]
|
exports: [UsersService],
|
||||||
})
|
})
|
||||||
export class UsersModule {}
|
export class UsersModule {}
|
||||||
|
|||||||
@@ -3,15 +3,21 @@ import {
|
|||||||
Injectable,
|
Injectable,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { UserRepository } from './user.repository';
|
import { UserRepository } from './repositories/user.repository';
|
||||||
import { User } from './entities/user.entity';
|
import { User } from './entities/user.entity';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import { CreateUserDto } from './DTO/create-user.dto';
|
import { CreateUserDto } from './DTO/create-user.dto';
|
||||||
import { UserMessages } from 'src/common/enums/messages.enum';
|
import { UserMessages, UserRoleMessages } from 'src/common/enums/messages.enum';
|
||||||
|
import { UserRole } from './entities/user-role.entity';
|
||||||
|
import { CreateUserRoleDto } from './DTO/create-user-role.dto';
|
||||||
|
import { UserRoleRepository } from './repositories/user-role.repository';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
constructor(private readonly userRepository: UserRepository) {}
|
constructor(
|
||||||
|
private readonly userRepository: UserRepository,
|
||||||
|
private readonly userRoleRepository: UserRoleRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
async findOneOrFail(id: string): Promise<User> {
|
async findOneOrFail(id: string): Promise<User> {
|
||||||
const user = await this.userRepository.findOne({ where: { id } });
|
const user = await this.userRepository.findOne({ where: { id } });
|
||||||
@@ -59,4 +65,32 @@ export class UsersService {
|
|||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async createUserRole(
|
||||||
|
userId: string,
|
||||||
|
userRoleDto: CreateUserRoleDto,
|
||||||
|
): Promise<UserRole> {
|
||||||
|
const existingRole = await this.userRoleRepository.findOne({
|
||||||
|
where: {
|
||||||
|
user: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
role: userRoleDto.role,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingRole)
|
||||||
|
throw new BadRequestException(UserRoleMessages.USER_ROLE_ALREADY_EXISTS);
|
||||||
|
|
||||||
|
const userRole = this.userRoleRepository.create({
|
||||||
|
user: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
role: userRoleDto.role,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.userRoleRepository.save(userRole);
|
||||||
|
|
||||||
|
return userRole;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user