Remove USER role

This commit is contained in:
faris Aljohari
2024-05-18 23:00:22 +03:00
parent 1bc8fee061
commit 6415d78992
23 changed files with 107 additions and 136 deletions

View File

@ -4,5 +4,5 @@ export class AuthInterface {
uuid: string;
sessionId: string;
id: number;
roles: string[];
roles?: string[];
}

View File

@ -22,7 +22,7 @@ export class AuthService {
where: {
email,
},
relations: ['role.roleType'],
relations: ['roles.roleType'],
});
if (!user.isUserVerified) {
@ -70,7 +70,7 @@ export class AuthService {
uuid: user.uuid,
type: user.type,
sessionId: user.sessionId,
roles: user.roles,
roles: user?.roles,
};
const tokens = await this.getTokens(payload);

View File

@ -31,7 +31,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
userUuid: payload.uuid,
uuid: payload.uuid,
sessionId: payload.sessionId,
roles: payload.roles,
roles: payload?.roles,
};
} else {
throw new BadRequestException('Unauthorized');

View File

@ -34,7 +34,7 @@ export class RefreshTokenStrategy extends PassportStrategy(
userUuid: payload.uuid,
uuid: payload.uuid,
sessionId: payload.sessionId,
roles: payload.roles,
roles: payload?.roles,
};
} else {
throw new BadRequestException('Unauthorized');

View File

@ -1,5 +1,4 @@
export enum RoleType {
SUPER_ADMIN = 'SUPER_ADMIN',
ADMIN = 'ADMIN',
USER = 'USER',
}

View File

@ -15,7 +15,7 @@ export class RoleTypeEntity extends AbstractEntity<RoleTypeDto> {
@OneToMany(() => UserRoleEntity, (role) => role.roleType, {
nullable: true,
})
role: UserRoleEntity[];
roles: UserRoleEntity[];
constructor(partial: Partial<RoleTypeEntity>) {
super();
Object.assign(this, partial);

View File

@ -7,12 +7,12 @@ import { RoleTypeEntity } from '../../role-type/entities';
@Entity({ name: 'user-role' })
@Unique(['user', 'roleType'])
export class UserRoleEntity extends AbstractEntity<UserRoleDto> {
@ManyToOne(() => UserEntity, (user) => user.role, {
@ManyToOne(() => UserEntity, (user) => user.roles, {
nullable: false,
})
user: UserEntity;
@ManyToOne(() => RoleTypeEntity, (roleType) => roleType.role, {
@ManyToOne(() => RoleTypeEntity, (roleType) => roleType.roles, {
nullable: false,
})
roleType: RoleTypeEntity;

View File

@ -62,7 +62,7 @@ export class UserEntity extends AbstractEntity<UserDto> {
@OneToMany(() => UserRoleEntity, (role) => role.user, {
nullable: true,
})
role: UserRoleEntity[];
roles: UserRoleEntity[];
constructor(partial: Partial<UserEntity>) {
super();
Object.assign(this, partial);

View File

@ -19,9 +19,7 @@ export class RoleTypeSeeder {
if (!roleTypeNames.includes(RoleType.ADMIN)) {
missingRoleTypes.push(RoleType.ADMIN);
}
if (!roleTypeNames.includes(RoleType.USER)) {
missingRoleTypes.push(RoleType.USER);
}
if (missingRoleTypes.length > 0) {
await this.addRoleTypeData(missingRoleTypes);
}

View File

@ -50,15 +50,6 @@ export class UserAuthService {
password: hashedPassword,
});
const defaultUserRoleUuid = await this.getRoleUuidByRoleType(
RoleType.USER,
);
await this.userRoleRepository.save({
user: { uuid: user.uuid },
roleType: { uuid: defaultUserRoleUuid },
});
return user;
} catch (error) {
throw new BadRequestException('Failed to register user');
@ -114,7 +105,7 @@ export class UserAuthService {
email: user.email,
userId: user.uuid,
uuid: user.uuid,
roles: user.role.map((role) => {
roles: user?.roles?.map((role) => {
return { uuid: role.uuid, type: role.roleType.type };
}),
sessionId: session[1].uuid,
@ -214,11 +205,4 @@ export class UserAuthService {
await this.authService.updateRefreshToken(user.uuid, tokens.refreshToken);
return tokens;
}
private async getRoleUuidByRoleType(roleType: string) {
const role = await this.roleTypeRepository.findOne({
where: { type: roleType },
});
return role.uuid;
}
}

View File

@ -18,7 +18,7 @@ import { UpdateBuildingNameDto } from '../dtos/update.building.dto';
import { CheckCommunityTypeGuard } from 'src/guards/community.type.guard';
import { CheckUserBuildingGuard } from 'src/guards/user.building.guard';
import { AdminRoleGuard } from 'src/guards/admin.role.guard';
import { UserRoleGuard } from 'src/guards/user.role.guard';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
@ApiTags('Building Module')
@Controller({
@ -44,7 +44,7 @@ export class BuildingController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get(':buildingUuid')
async getBuildingByUuid(@Param('buildingUuid') buildingUuid: string) {
try {
@ -60,7 +60,7 @@ export class BuildingController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('child/:buildingUuid')
async getBuildingChildByUuid(
@Param('buildingUuid') buildingUuid: string,
@ -80,7 +80,7 @@ export class BuildingController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('parent/:buildingUuid')
async getBuildingParentByUuid(@Param('buildingUuid') buildingUuid: string) {
try {
@ -109,7 +109,7 @@ export class BuildingController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('user/:userUuid')
async getBuildingsByUserId(@Param('userUuid') userUuid: string) {
try {
@ -123,7 +123,7 @@ export class BuildingController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Put('rename/:buildingUuid')
async renameBuildingByUuid(
@Param('buildingUuid') buildingUuid: string,

View File

@ -20,7 +20,7 @@ import { GetCommunityChildDto } from '../dtos/get.community.dto';
import { UpdateCommunityNameDto } from '../dtos/update.community.dto';
import { CheckUserCommunityGuard } from 'src/guards/user.community.guard';
import { AdminRoleGuard } from 'src/guards/admin.role.guard';
import { UserRoleGuard } from 'src/guards/user.role.guard';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
@ApiTags('Community Module')
@Controller({
@ -47,7 +47,7 @@ export class CommunityController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get(':communityUuid')
async getCommunityByUuid(@Param('communityUuid') communityUuid: string) {
try {
@ -63,7 +63,7 @@ export class CommunityController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('child/:communityUuid')
async getCommunityChildByUuid(
@Param('communityUuid') communityUuid: string,
@ -84,7 +84,7 @@ export class CommunityController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('user/:userUuid')
async getCommunitiesByUserId(@Param('userUuid') userUuid: string) {
try {
@ -111,7 +111,7 @@ export class CommunityController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Put('rename/:communityUuid')
async renameCommunityByUuid(
@Param('communityUuid') communityUuid: string,

View File

@ -25,7 +25,7 @@ import { CheckRoomGuard } from 'src/guards/room.guard';
import { CheckGroupGuard } from 'src/guards/group.guard';
import { CheckUserHavePermission } from 'src/guards/user.device.permission.guard';
import { CheckUserHaveControllablePermission } from 'src/guards/user.device.controllable.permission.guard';
import { UserRoleGuard } from 'src/guards/user.role.guard';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
@ApiTags('Device Module')
@Controller({
@ -36,7 +36,7 @@ export class DeviceController {
constructor(private readonly deviceService: DeviceService) {}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckRoomGuard)
@UseGuards(JwtAuthGuard, CheckRoomGuard)
@Get('room')
async getDevicesByRoomId(
@Query() getDeviceByRoomUuidDto: GetDeviceByRoomUuidDto,
@ -57,7 +57,7 @@ export class DeviceController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckRoomGuard)
@UseGuards(JwtAuthGuard, CheckRoomGuard)
@Post('room')
async addDeviceInRoom(@Body() addDeviceInRoomDto: AddDeviceInRoomDto) {
try {
@ -70,7 +70,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckGroupGuard)
@UseGuards(JwtAuthGuard, CheckGroupGuard)
@Get('group')
async getDevicesByGroupId(
@Query() getDeviceByGroupIdDto: GetDeviceByGroupIdDto,
@ -90,7 +90,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckGroupGuard)
@UseGuards(JwtAuthGuard, CheckGroupGuard)
@Post('group')
async addDeviceInGroup(@Body() addDeviceInGroupDto: AddDeviceInGroupDto) {
try {
@ -103,7 +103,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckUserHavePermission)
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
@Get(':deviceUuid')
async getDeviceDetailsByDeviceId(
@Param('deviceUuid') deviceUuid: string,
@ -123,7 +123,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckUserHavePermission)
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
@Get(':deviceUuid/functions')
async getDeviceInstructionByDeviceId(
@Param('deviceUuid') deviceUuid: string,
@ -140,7 +140,7 @@ export class DeviceController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckUserHavePermission)
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
@Get(':deviceUuid/functions/status')
async getDevicesInstructionStatus(@Param('deviceUuid') deviceUuid: string) {
try {
@ -154,7 +154,7 @@ export class DeviceController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckUserHaveControllablePermission)
@UseGuards(JwtAuthGuard, CheckUserHaveControllablePermission)
@Post(':deviceUuid/control')
async controlDevice(
@Body() controlDeviceDto: ControlDeviceDto,

View File

@ -17,7 +17,7 @@ import { GetFloorChildDto } from '../dtos/get.floor.dto';
import { UpdateFloorNameDto } from '../dtos/update.floor.dto';
import { CheckBuildingTypeGuard } from 'src/guards/building.type.guard';
import { CheckUserFloorGuard } from 'src/guards/user.floor.guard';
import { UserRoleGuard } from 'src/guards/user.role.guard';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
import { AdminRoleGuard } from 'src/guards/admin.role.guard';
@ApiTags('Floor Module')
@ -44,7 +44,7 @@ export class FloorController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get(':floorUuid')
async getFloorByUuid(@Param('floorUuid') floorUuid: string) {
try {
@ -59,7 +59,7 @@ export class FloorController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('child/:floorUuid')
async getFloorChildByUuid(
@Param('floorUuid') floorUuid: string,
@ -79,7 +79,7 @@ export class FloorController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('parent/:floorUuid')
async getFloorParentByUuid(@Param('floorUuid') floorUuid: string) {
try {
@ -109,7 +109,7 @@ export class FloorController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('user/:userUuid')
async getFloorsByUserId(@Param('userUuid') userUuid: string) {
try {
@ -123,7 +123,7 @@ export class FloorController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Put('rename/:floorUuid')
async renameFloorByUuid(
@Param('floorUuid') floorUuid: string,

View File

@ -16,7 +16,7 @@ import { AddGroupDto } from '../dtos/add.group.dto';
import { ControlGroupDto } from '../dtos/control.group.dto';
import { RenameGroupDto } from '../dtos/rename.group.dto copy';
import { CheckProductUuidForAllDevicesGuard } from 'src/guards/device.product.guard';
import { UserRoleGuard } from 'src/guards/user.role.guard';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
@ApiTags('Group Module')
@Controller({
@ -27,7 +27,7 @@ export class GroupController {
constructor(private readonly groupService: GroupService) {}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('space/:spaceUuid')
async getGroupsBySpaceUuid(@Param('spaceUuid') spaceUuid: string) {
try {
@ -40,7 +40,7 @@ export class GroupController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get(':groupUuid')
async getGroupsByGroupId(@Param('groupUuid') groupUuid: string) {
try {
@ -53,7 +53,7 @@ export class GroupController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard, CheckProductUuidForAllDevicesGuard)
@UseGuards(JwtAuthGuard, CheckProductUuidForAllDevicesGuard)
@Post()
async addGroup(@Body() addGroupDto: AddGroupDto) {
try {
@ -67,7 +67,7 @@ export class GroupController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Post('control')
async controlGroup(@Body() controlGroupDto: ControlGroupDto) {
try {
@ -81,7 +81,7 @@ export class GroupController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Put('rename/:groupUuid')
async renameGroupByUuid(
@Param('groupUuid') groupUuid: string,
@ -101,7 +101,7 @@ export class GroupController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Delete(':groupUuid')
async deleteGroup(@Param('groupUuid') groupUuid: string) {
try {

View File

@ -1,24 +0,0 @@
import { RoleType } from '@app/common/constants/role.type.enum';
import { BadRequestException, UnauthorizedException } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
export class UserRoleGuard extends AuthGuard('jwt') {
handleRequest(err, user) {
if (err || !user) {
throw err || new UnauthorizedException();
} else {
const isUserOrAdmin = user.roles.some(
(role) =>
role.type === RoleType.SUPER_ADMIN ||
role.type === RoleType.ADMIN ||
role.type === RoleType.USER,
);
if (!isUserOrAdmin) {
throw new BadRequestException(
'Only admin or user role can access this route',
);
}
}
return user;
}
}

View File

@ -4,13 +4,12 @@ import {
Get,
HttpException,
HttpStatus,
Param,
Put,
Post,
UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { RoleService } from '../services/role.service';
import { UserRoleEditDto } from '../dtos';
import { AddUserRoleDto } from '../dtos';
import { SuperAdminRoleGuard } from 'src/guards/super.admin.role.guard';
@ApiTags('Role Module')
@ -37,16 +36,13 @@ export class RoleController {
}
@ApiBearerAuth()
@UseGuards(SuperAdminRoleGuard)
@Put('edit/user/:userUuid')
async editUserRoleType(
@Param('userUuid') userUuid: string,
@Body() userRoleEditDto: UserRoleEditDto,
) {
@Post()
async addUserRoleType(@Body() addUserRoleDto: AddUserRoleDto) {
try {
await this.roleService.editUserRoleType(userUuid, userRoleEditDto);
await this.roleService.addUserRoleType(addUserRoleDto);
return {
statusCode: HttpStatus.OK,
message: 'User Role Updated Successfully',
message: 'User Role Added Successfully',
};
} catch (error) {
throw new HttpException(

View File

@ -1 +1 @@
export * from './role.edit.dto';
export * from './role.add.dto';

View File

@ -0,0 +1,24 @@
import { RoleType } from '@app/common/constants/role.type.enum';
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsIn, IsNotEmpty, IsString } from 'class-validator';
export class AddUserRoleDto {
@ApiProperty({
description: 'userUuid',
required: true,
})
@IsString()
@IsNotEmpty()
public userUuid: string;
@ApiProperty({
description: 'Role type (ADMIN)',
enum: [RoleType.ADMIN],
required: true,
})
@IsEnum(RoleType)
@IsIn([RoleType.ADMIN], {
message: 'roleType must be one of the following values: ADMIN',
})
roleType: RoleType;
}

View File

@ -1,16 +0,0 @@
import { RoleType } from '@app/common/constants/role.type.enum';
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsIn } from 'class-validator';
export class UserRoleEditDto {
@ApiProperty({
description: 'Role type (USER or ADMIN)',
enum: [RoleType.USER, RoleType.ADMIN],
required: true,
})
@IsEnum(RoleType)
@IsIn([RoleType.USER, RoleType.ADMIN], {
message: 'roleType must be one of the following values: USER, ADMIN',
})
roleType: RoleType;
}

View File

@ -1,7 +1,8 @@
import { RoleTypeRepository } from './../../../libs/common/src/modules/role-type/repositories/role.type.repository';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { UserRoleEditDto } from '../dtos/role.edit.dto';
import { AddUserRoleDto } from '../dtos/role.add.dto';
import { UserRoleRepository } from '@app/common/modules/user-role/repositories';
import { QueryFailedError } from 'typeorm';
@Injectable()
export class RoleService {
@ -10,18 +11,27 @@ export class RoleService {
private readonly userRoleRepository: UserRoleRepository,
) {}
async editUserRoleType(userUuid: string, userRoleEditDto: UserRoleEditDto) {
async addUserRoleType(addUserRoleDto: AddUserRoleDto) {
try {
const roleType = await this.fetchRoleByType(userRoleEditDto.roleType);
return await this.userRoleRepository.update(
{ user: { uuid: userUuid } },
{
roleType: {
uuid: roleType.uuid,
},
},
);
const roleType = await this.fetchRoleByType(addUserRoleDto.roleType);
if (roleType.uuid) {
return await this.userRoleRepository.save({
user: { uuid: addUserRoleDto.userUuid },
roleType: { uuid: roleType.uuid },
});
}
} catch (error) {
if (
error instanceof QueryFailedError &&
error.driverError.code === '23505'
) {
// Postgres unique constraint violation error code
throw new HttpException(
'This role already exists for this user',
HttpStatus.CONFLICT,
);
}
throw new HttpException(
error.message || 'Internal Server Error',
HttpStatus.INTERNAL_SERVER_ERROR,

View File

@ -16,7 +16,7 @@ import { UpdateRoomNameDto } from '../dtos/update.room.dto';
import { CheckUnitTypeGuard } from 'src/guards/unit.type.guard';
import { CheckUserRoomGuard } from 'src/guards/user.room.guard';
import { AdminRoleGuard } from 'src/guards/admin.role.guard';
import { UserRoleGuard } from 'src/guards/user.role.guard';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
@ApiTags('Room Module')
@Controller({
@ -42,7 +42,7 @@ export class RoomController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get(':roomUuid')
async getRoomByUuid(@Param('roomUuid') roomUuid: string) {
try {
@ -57,7 +57,7 @@ export class RoomController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('parent/:roomUuid')
async getRoomParentByUuid(@Param('roomUuid') roomUuid: string) {
try {
@ -85,7 +85,7 @@ export class RoomController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('user/:userUuid')
async getRoomsByUserId(@Param('userUuid') userUuid: string) {
try {
@ -99,7 +99,7 @@ export class RoomController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Put('rename/:roomUuid')
async renameRoomByUuid(
@Param('roomUuid') roomUuid: string,

View File

@ -18,7 +18,7 @@ import { UpdateUnitNameDto } from '../dtos/update.unit.dto';
import { CheckFloorTypeGuard } from 'src/guards/floor.type.guard';
import { CheckUserUnitGuard } from 'src/guards/user.unit.guard';
import { AdminRoleGuard } from 'src/guards/admin.role.guard';
import { UserRoleGuard } from 'src/guards/user.role.guard';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
@ApiTags('Unit Module')
@Controller({
@ -44,7 +44,7 @@ export class UnitController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get(':unitUuid')
async getUnitByUuid(@Param('unitUuid') unitUuid: string) {
try {
@ -59,7 +59,7 @@ export class UnitController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('child/:unitUuid')
async getUnitChildByUuid(
@Param('unitUuid') unitUuid: string,
@ -76,7 +76,7 @@ export class UnitController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('parent/:unitUuid')
async getUnitParentByUuid(@Param('unitUuid') unitUuid: string) {
try {
@ -104,7 +104,7 @@ export class UnitController {
}
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Get('user/:userUuid')
async getUnitsByUserId(@Param('userUuid') userUuid: string) {
try {
@ -118,7 +118,7 @@ export class UnitController {
}
@ApiBearerAuth()
@UseGuards(UserRoleGuard)
@UseGuards(JwtAuthGuard)
@Put('rename/:unitUuid')
async renameUnitByUuid(
@Param('unitUuid') unitUuid: string,