mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-15 10:25:23 +00:00
Merge branch 'SP-205-be-user-device-permission' into SP-201-be-handle-roles
This commit is contained in:
@ -6,16 +6,14 @@ import { UserEntity } from '../modules/user/entities/user.entity';
|
|||||||
import { UserSessionEntity } from '../modules/session/entities/session.entity';
|
import { UserSessionEntity } from '../modules/session/entities/session.entity';
|
||||||
import { UserOtpEntity } from '../modules/user-otp/entities';
|
import { UserOtpEntity } from '../modules/user-otp/entities';
|
||||||
import { ProductEntity } from '../modules/product/entities';
|
import { ProductEntity } from '../modules/product/entities';
|
||||||
import {
|
import { DeviceEntity } from '../modules/device/entities';
|
||||||
DeviceEntity,
|
|
||||||
DeviceUserPermissionEntity,
|
|
||||||
} from '../modules/device/entities';
|
|
||||||
import { PermissionTypeEntity } from '../modules/permission/entities';
|
import { PermissionTypeEntity } from '../modules/permission/entities';
|
||||||
import { SpaceEntity } from '../modules/space/entities';
|
import { SpaceEntity } from '../modules/space/entities';
|
||||||
import { SpaceTypeEntity } from '../modules/space-type/entities';
|
import { SpaceTypeEntity } from '../modules/space-type/entities';
|
||||||
import { UserSpaceEntity } from '../modules/user-space/entities';
|
import { UserSpaceEntity } from '../modules/user-space/entities';
|
||||||
import { GroupEntity } from '../modules/group/entities';
|
import { GroupEntity } from '../modules/group/entities';
|
||||||
import { GroupDeviceEntity } from '../modules/group-device/entities';
|
import { GroupDeviceEntity } from '../modules/group-device/entities';
|
||||||
|
import { DeviceUserPermissionEntity } from '../modules/device-user-permission/entities';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -43,6 +41,7 @@ import { GroupDeviceEntity } from '../modules/group-device/entities';
|
|||||||
UserSpaceEntity,
|
UserSpaceEntity,
|
||||||
GroupEntity,
|
GroupEntity,
|
||||||
GroupDeviceEntity,
|
GroupDeviceEntity,
|
||||||
|
DeviceUserPermissionEntity,
|
||||||
],
|
],
|
||||||
namingStrategy: new SnakeNamingStrategy(),
|
namingStrategy: new SnakeNamingStrategy(),
|
||||||
synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))),
|
synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))),
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { DeviceUserPermissionEntity } from './entities';
|
||||||
|
@Module({
|
||||||
|
providers: [],
|
||||||
|
exports: [],
|
||||||
|
controllers: [],
|
||||||
|
imports: [TypeOrmModule.forFeature([DeviceUserPermissionEntity])],
|
||||||
|
})
|
||||||
|
export class DeviceUserPermissionRepositoryModule {}
|
@ -1,6 +1,6 @@
|
|||||||
import { IsNotEmpty, IsString } from 'class-validator';
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class DeviceUserTypeDto {
|
export class DeviceUserPermissionDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public uuid: string;
|
public uuid: string;
|
@ -0,0 +1 @@
|
|||||||
|
export * from './device.user.permission.dto';
|
@ -0,0 +1,43 @@
|
|||||||
|
import { Column, Entity, ManyToOne, Unique } from 'typeorm';
|
||||||
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
|
import { DeviceUserPermissionDto } from '../dtos';
|
||||||
|
import { PermissionTypeEntity } from '../../permission/entities';
|
||||||
|
import { DeviceEntity } from '../../device/entities';
|
||||||
|
import { UserEntity } from '../../user/entities';
|
||||||
|
|
||||||
|
@Entity({ name: 'device-user-permission' })
|
||||||
|
@Unique(['userUuid', 'deviceUuid'])
|
||||||
|
export class DeviceUserPermissionEntity extends AbstractEntity<DeviceUserPermissionDto> {
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
public userUuid: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
deviceUuid: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => DeviceEntity, (device) => device.permission, {
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
device: DeviceEntity;
|
||||||
|
|
||||||
|
@ManyToOne(
|
||||||
|
() => PermissionTypeEntity,
|
||||||
|
(permissionType) => permissionType.permission,
|
||||||
|
{
|
||||||
|
nullable: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
permissionType: PermissionTypeEntity;
|
||||||
|
|
||||||
|
@ManyToOne(() => UserEntity, (user) => user.userPermission, {
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
user: UserEntity;
|
||||||
|
constructor(partial: Partial<DeviceUserPermissionEntity>) {
|
||||||
|
super();
|
||||||
|
Object.assign(this, partial);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export * from './device.user.permission.entity';
|
@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { DeviceUserPermissionEntity } from '../entities';
|
import { DeviceUserPermissionEntity } from '../entities';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeviceUserTypeRepository extends Repository<DeviceUserPermissionEntity> {
|
export class DeviceUserPermissionRepository extends Repository<DeviceUserPermissionEntity> {
|
||||||
constructor(private dataSource: DataSource) {
|
constructor(private dataSource: DataSource) {
|
||||||
super(DeviceUserPermissionEntity, dataSource.createEntityManager());
|
super(DeviceUserPermissionEntity, dataSource.createEntityManager());
|
||||||
}
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export * from './device.user.permission.repository';
|
@ -1,13 +1,11 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { DeviceEntity, DeviceUserPermissionEntity } from './entities';
|
import { DeviceEntity } from './entities';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
providers: [],
|
providers: [],
|
||||||
exports: [],
|
exports: [],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
imports: [
|
imports: [TypeOrmModule.forFeature([DeviceEntity])],
|
||||||
TypeOrmModule.forFeature([DeviceEntity, DeviceUserPermissionEntity]),
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class DeviceRepositoryModule {}
|
export class DeviceRepositoryModule {}
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export * from './device.dto';
|
export * from './device.dto';
|
||||||
export * from './device-user-type.dto';
|
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
|
||||||
import { DeviceUserTypeDto } from '../dtos/device-user-type.dto';
|
|
||||||
import { DeviceEntity } from './device.entity';
|
|
||||||
import { PermissionTypeEntity } from '../../permission/entities';
|
|
||||||
|
|
||||||
@Entity({ name: 'device-user-permission' })
|
|
||||||
export class DeviceUserPermissionEntity extends AbstractEntity<DeviceUserTypeDto> {
|
|
||||||
@Column({
|
|
||||||
nullable: false,
|
|
||||||
})
|
|
||||||
public userUuid: string;
|
|
||||||
|
|
||||||
@Column({
|
|
||||||
nullable: false,
|
|
||||||
})
|
|
||||||
deviceUuid: string;
|
|
||||||
|
|
||||||
@Column({
|
|
||||||
nullable: false,
|
|
||||||
})
|
|
||||||
public permissionTypeUuid: string;
|
|
||||||
|
|
||||||
@ManyToOne(() => DeviceEntity, {
|
|
||||||
onDelete: 'CASCADE',
|
|
||||||
onUpdate: 'CASCADE',
|
|
||||||
})
|
|
||||||
@JoinColumn({ name: 'device_uuid', referencedColumnName: 'uuid' })
|
|
||||||
device: DeviceEntity;
|
|
||||||
|
|
||||||
@ManyToOne(() => PermissionTypeEntity, {
|
|
||||||
onDelete: 'CASCADE',
|
|
||||||
onUpdate: 'CASCADE',
|
|
||||||
})
|
|
||||||
@JoinColumn({ name: 'permission_type_uuid', referencedColumnName: 'uuid' })
|
|
||||||
type: PermissionTypeEntity;
|
|
||||||
|
|
||||||
constructor(partial: Partial<DeviceUserPermissionEntity>) {
|
|
||||||
super();
|
|
||||||
Object.assign(this, partial);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,10 @@
|
|||||||
import { Column, Entity, ManyToOne, OneToMany, Unique } from 'typeorm';
|
import { Column, Entity, ManyToOne, OneToMany, Unique } from 'typeorm';
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { DeviceDto } from '../dtos/device.dto';
|
import { DeviceDto } from '../dtos/device.dto';
|
||||||
import { DeviceUserPermissionEntity } from './device-user-type.entity';
|
|
||||||
import { GroupDeviceEntity } from '../../group-device/entities';
|
import { GroupDeviceEntity } from '../../group-device/entities';
|
||||||
import { SpaceEntity } from '../../space/entities';
|
import { SpaceEntity } from '../../space/entities';
|
||||||
import { ProductEntity } from '../../product/entities';
|
import { ProductEntity } from '../../product/entities';
|
||||||
|
import { DeviceUserPermissionEntity } from '../../device-user-permission/entities';
|
||||||
|
|
||||||
@Entity({ name: 'device' })
|
@Entity({ name: 'device' })
|
||||||
@Unique(['spaceDevice', 'deviceTuyaUuid'])
|
@Unique(['spaceDevice', 'deviceTuyaUuid'])
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export * from './device.entity';
|
export * from './device.entity';
|
||||||
export * from './device-user-type.entity';
|
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export * from './device.repository';
|
export * from './device.repository';
|
||||||
export * from './device-user-type.repository';
|
|
||||||
|
@ -2,7 +2,7 @@ import { Column, Entity, OneToMany } from 'typeorm';
|
|||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
||||||
import { PermissionTypeDto } from '../dtos/permission.dto';
|
import { PermissionTypeDto } from '../dtos/permission.dto';
|
||||||
import { DeviceUserPermissionEntity } from '../../device/entities';
|
import { DeviceUserPermissionEntity } from '../../device-user-permission/entities';
|
||||||
|
|
||||||
@Entity({ name: 'permission-type' })
|
@Entity({ name: 'permission-type' })
|
||||||
export class PermissionTypeEntity extends AbstractEntity<PermissionTypeDto> {
|
export class PermissionTypeEntity extends AbstractEntity<PermissionTypeDto> {
|
||||||
@ -14,7 +14,7 @@ export class PermissionTypeEntity extends AbstractEntity<PermissionTypeDto> {
|
|||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
() => DeviceUserPermissionEntity,
|
() => DeviceUserPermissionEntity,
|
||||||
(permission) => permission.type,
|
(permission) => permission.permissionType,
|
||||||
{
|
{
|
||||||
nullable: true,
|
nullable: true,
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { DeviceUserPermissionEntity } from '../../device-user-permission/entities/device.user.permission.entity';
|
||||||
import { Column, Entity, OneToMany } from 'typeorm';
|
import { Column, Entity, OneToMany } from 'typeorm';
|
||||||
import { UserDto } from '../dtos';
|
import { UserDto } from '../dtos';
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
@ -51,6 +52,11 @@ export class UserEntity extends AbstractEntity<UserDto> {
|
|||||||
@OneToMany(() => UserSpaceEntity, (userSpace) => userSpace.user)
|
@OneToMany(() => UserSpaceEntity, (userSpace) => userSpace.user)
|
||||||
userSpaces: UserSpaceEntity[];
|
userSpaces: UserSpaceEntity[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => DeviceUserPermissionEntity,
|
||||||
|
(userPermission) => userPermission.user,
|
||||||
|
)
|
||||||
|
userPermission: DeviceUserPermissionEntity[];
|
||||||
constructor(partial: Partial<UserEntity>) {
|
constructor(partial: Partial<UserEntity>) {
|
||||||
super();
|
super();
|
||||||
Object.assign(this, partial);
|
Object.assign(this, partial);
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
HttpException,
|
HttpException,
|
||||||
HttpStatus,
|
HttpStatus,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
|
Req,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
|
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
@ -23,6 +24,8 @@ import { ControlDeviceDto } from '../dtos/control.device.dto';
|
|||||||
import { CheckRoomGuard } from 'src/guards/room.guard';
|
import { CheckRoomGuard } from 'src/guards/room.guard';
|
||||||
import { CheckGroupGuard } from 'src/guards/group.guard';
|
import { CheckGroupGuard } from 'src/guards/group.guard';
|
||||||
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
|
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
|
||||||
|
import { CheckUserHavePermission } from 'src/guards/user.device.permission.guard';
|
||||||
|
import { CheckUserHaveControllablePermission } from 'src/guards/user.device.controllable.permission.guard';
|
||||||
|
|
||||||
@ApiTags('Device Module')
|
@ApiTags('Device Module')
|
||||||
@Controller({
|
@Controller({
|
||||||
@ -37,10 +40,13 @@ export class DeviceController {
|
|||||||
@Get('room')
|
@Get('room')
|
||||||
async getDevicesByRoomId(
|
async getDevicesByRoomId(
|
||||||
@Query() getDeviceByRoomUuidDto: GetDeviceByRoomUuidDto,
|
@Query() getDeviceByRoomUuidDto: GetDeviceByRoomUuidDto,
|
||||||
|
@Req() req: any,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
return await this.deviceService.getDevicesByRoomId(
|
return await this.deviceService.getDevicesByRoomId(
|
||||||
getDeviceByRoomUuidDto,
|
getDeviceByRoomUuidDto,
|
||||||
|
userUuid,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
@ -68,10 +74,13 @@ export class DeviceController {
|
|||||||
@Get('group')
|
@Get('group')
|
||||||
async getDevicesByGroupId(
|
async getDevicesByGroupId(
|
||||||
@Query() getDeviceByGroupIdDto: GetDeviceByGroupIdDto,
|
@Query() getDeviceByGroupIdDto: GetDeviceByGroupIdDto,
|
||||||
|
@Req() req: any,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
return await this.deviceService.getDevicesByGroupId(
|
return await this.deviceService.getDevicesByGroupId(
|
||||||
getDeviceByGroupIdDto,
|
getDeviceByGroupIdDto,
|
||||||
|
userUuid,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
@ -94,11 +103,18 @@ export class DeviceController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
|
||||||
@Get(':deviceUuid')
|
@Get(':deviceUuid')
|
||||||
async getDeviceDetailsByDeviceId(@Param('deviceUuid') deviceUuid: string) {
|
async getDeviceDetailsByDeviceId(
|
||||||
|
@Param('deviceUuid') deviceUuid: string,
|
||||||
|
@Req() req: any,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
return await this.deviceService.getDeviceDetailsByDeviceId(deviceUuid);
|
const userUuid = req.user.uuid;
|
||||||
|
return await this.deviceService.getDeviceDetailsByDeviceId(
|
||||||
|
deviceUuid,
|
||||||
|
userUuid,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
error.message || 'Internal server error',
|
error.message || 'Internal server error',
|
||||||
@ -107,7 +123,7 @@ export class DeviceController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
|
||||||
@Get(':deviceUuid/functions')
|
@Get(':deviceUuid/functions')
|
||||||
async getDeviceInstructionByDeviceId(
|
async getDeviceInstructionByDeviceId(
|
||||||
@Param('deviceUuid') deviceUuid: string,
|
@Param('deviceUuid') deviceUuid: string,
|
||||||
@ -124,7 +140,7 @@ export class DeviceController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
|
||||||
@Get(':deviceUuid/functions/status')
|
@Get(':deviceUuid/functions/status')
|
||||||
async getDevicesInstructionStatus(@Param('deviceUuid') deviceUuid: string) {
|
async getDevicesInstructionStatus(@Param('deviceUuid') deviceUuid: string) {
|
||||||
try {
|
try {
|
||||||
@ -138,11 +154,17 @@ export class DeviceController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard, CheckUserHaveControllablePermission)
|
||||||
@Post('control')
|
@Post(':deviceUuid/control')
|
||||||
async controlDevice(@Body() controlDeviceDto: ControlDeviceDto) {
|
async controlDevice(
|
||||||
|
@Body() controlDeviceDto: ControlDeviceDto,
|
||||||
|
@Param('deviceUuid') deviceUuid: string,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
return await this.deviceService.controlDevice(controlDeviceDto);
|
return await this.deviceService.controlDevice(
|
||||||
|
controlDeviceDto,
|
||||||
|
deviceUuid,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
error.message || 'Internal server error',
|
error.message || 'Internal server error',
|
||||||
|
@ -5,15 +5,14 @@ import { ConfigModule } from '@nestjs/config';
|
|||||||
import { ProductRepositoryModule } from '@app/common/modules/product/product.repository.module';
|
import { ProductRepositoryModule } from '@app/common/modules/product/product.repository.module';
|
||||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||||
import { DeviceRepositoryModule } from '@app/common/modules/device';
|
import { DeviceRepositoryModule } from '@app/common/modules/device';
|
||||||
import {
|
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||||
DeviceRepository,
|
|
||||||
DeviceUserTypeRepository,
|
|
||||||
} from '@app/common/modules/device/repositories';
|
|
||||||
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
|
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
|
||||||
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
||||||
import { GroupDeviceRepository } from '@app/common/modules/group-device/repositories';
|
import { GroupDeviceRepository } from '@app/common/modules/group-device/repositories';
|
||||||
import { GroupRepository } from '@app/common/modules/group/repositories';
|
import { GroupRepository } from '@app/common/modules/group/repositories';
|
||||||
import { GroupRepositoryModule } from '@app/common/modules/group/group.repository.module';
|
import { GroupRepositoryModule } from '@app/common/modules/group/group.repository.module';
|
||||||
|
import { DeviceUserPermissionRepository } from '@app/common/modules/device-user-permission/repositories';
|
||||||
|
import { UserRepository } from '@app/common/modules/user/repositories';
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule,
|
ConfigModule,
|
||||||
@ -25,12 +24,13 @@ import { GroupRepositoryModule } from '@app/common/modules/group/group.repositor
|
|||||||
providers: [
|
providers: [
|
||||||
DeviceService,
|
DeviceService,
|
||||||
ProductRepository,
|
ProductRepository,
|
||||||
DeviceUserTypeRepository,
|
DeviceUserPermissionRepository,
|
||||||
PermissionTypeRepository,
|
PermissionTypeRepository,
|
||||||
SpaceRepository,
|
SpaceRepository,
|
||||||
DeviceRepository,
|
DeviceRepository,
|
||||||
GroupDeviceRepository,
|
GroupDeviceRepository,
|
||||||
GroupRepository,
|
GroupRepository,
|
||||||
|
UserRepository,
|
||||||
],
|
],
|
||||||
exports: [DeviceService],
|
exports: [DeviceService],
|
||||||
})
|
})
|
||||||
|
@ -2,14 +2,6 @@ import { ApiProperty } from '@nestjs/swagger';
|
|||||||
import { IsNotEmpty, IsString } from 'class-validator';
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class ControlDeviceDto {
|
export class ControlDeviceDto {
|
||||||
@ApiProperty({
|
|
||||||
description: 'deviceUuid',
|
|
||||||
required: true,
|
|
||||||
})
|
|
||||||
@IsString()
|
|
||||||
@IsNotEmpty()
|
|
||||||
public deviceUuid: string;
|
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'code',
|
description: 'code',
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -26,6 +26,7 @@ import { ControlDeviceDto } from '../dtos/control.device.dto';
|
|||||||
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
|
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
|
||||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||||
import { GroupDeviceRepository } from '@app/common/modules/group-device/repositories';
|
import { GroupDeviceRepository } from '@app/common/modules/group-device/repositories';
|
||||||
|
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeviceService {
|
export class DeviceService {
|
||||||
@ -47,13 +48,25 @@ export class DeviceService {
|
|||||||
|
|
||||||
async getDevicesByRoomId(
|
async getDevicesByRoomId(
|
||||||
getDeviceByRoomUuidDto: GetDeviceByRoomUuidDto,
|
getDeviceByRoomUuidDto: GetDeviceByRoomUuidDto,
|
||||||
|
userUuid: string,
|
||||||
): Promise<GetDeviceDetailsInterface[]> {
|
): Promise<GetDeviceDetailsInterface[]> {
|
||||||
try {
|
try {
|
||||||
const devices = await this.deviceRepository.find({
|
const devices = await this.deviceRepository.find({
|
||||||
where: {
|
where: {
|
||||||
spaceDevice: { uuid: getDeviceByRoomUuidDto.roomUuid },
|
spaceDevice: { uuid: getDeviceByRoomUuidDto.roomUuid },
|
||||||
|
permission: {
|
||||||
|
userUuid,
|
||||||
|
permissionType: {
|
||||||
|
type: PermissionType.READ || PermissionType.CONTROLLABLE,
|
||||||
},
|
},
|
||||||
relations: ['spaceDevice', 'productDevice'],
|
},
|
||||||
|
},
|
||||||
|
relations: [
|
||||||
|
'spaceDevice',
|
||||||
|
'productDevice',
|
||||||
|
'permission',
|
||||||
|
'permission.permissionType',
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const devicesData = await Promise.all(
|
const devicesData = await Promise.all(
|
||||||
devices.map(async (device) => {
|
devices.map(async (device) => {
|
||||||
@ -64,6 +77,7 @@ export class DeviceService {
|
|||||||
uuid: device.uuid,
|
uuid: device.uuid,
|
||||||
productUuid: device.productDevice.uuid,
|
productUuid: device.productDevice.uuid,
|
||||||
productType: device.productDevice.prodType,
|
productType: device.productDevice.prodType,
|
||||||
|
permissionType: device.permission[0].permissionType.type,
|
||||||
} as GetDeviceDetailsInterface;
|
} as GetDeviceDetailsInterface;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -77,11 +91,29 @@ export class DeviceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDevicesByGroupId(getDeviceByGroupIdDto: GetDeviceByGroupIdDto) {
|
async getDevicesByGroupId(
|
||||||
|
getDeviceByGroupIdDto: GetDeviceByGroupIdDto,
|
||||||
|
userUuid: string,
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const groupDevices = await this.groupDeviceRepository.find({
|
const groupDevices = await this.groupDeviceRepository.find({
|
||||||
where: { group: { uuid: getDeviceByGroupIdDto.groupUuid } },
|
where: {
|
||||||
relations: ['device'],
|
group: { uuid: getDeviceByGroupIdDto.groupUuid },
|
||||||
|
device: {
|
||||||
|
permission: {
|
||||||
|
userUuid,
|
||||||
|
permissionType: {
|
||||||
|
type: PermissionType.READ || PermissionType.CONTROLLABLE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
relations: [
|
||||||
|
'device',
|
||||||
|
'device.productDevice',
|
||||||
|
'device.permission',
|
||||||
|
'device.permission.permissionType',
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const devicesData = await Promise.all(
|
const devicesData = await Promise.all(
|
||||||
groupDevices.map(async (device) => {
|
groupDevices.map(async (device) => {
|
||||||
@ -89,9 +121,10 @@ export class DeviceService {
|
|||||||
...(await this.getDeviceDetailsByDeviceIdTuya(
|
...(await this.getDeviceDetailsByDeviceIdTuya(
|
||||||
device.device.deviceTuyaUuid,
|
device.device.deviceTuyaUuid,
|
||||||
)),
|
)),
|
||||||
uuid: device.uuid,
|
uuid: device.device.uuid,
|
||||||
productUuid: device.device.productDevice.uuid,
|
productUuid: device.device.productDevice.uuid,
|
||||||
productType: device.device.productDevice.prodType,
|
productType: device.device.productDevice.prodType,
|
||||||
|
permissionType: device.device.permission[0].permissionType.type,
|
||||||
} as GetDeviceDetailsInterface;
|
} as GetDeviceDetailsInterface;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -104,7 +137,6 @@ export class DeviceService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async addDeviceInRoom(addDeviceInRoomDto: AddDeviceInRoomDto) {
|
async addDeviceInRoom(addDeviceInRoomDto: AddDeviceInRoomDto) {
|
||||||
try {
|
try {
|
||||||
const device = await this.getDeviceDetailsByDeviceIdTuya(
|
const device = await this.getDeviceDetailsByDeviceIdTuya(
|
||||||
@ -158,11 +190,11 @@ export class DeviceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async controlDevice(controlDeviceDto: ControlDeviceDto) {
|
async controlDevice(controlDeviceDto: ControlDeviceDto, deviceUuid: string) {
|
||||||
try {
|
try {
|
||||||
const deviceDetails = await this.deviceRepository.findOne({
|
const deviceDetails = await this.deviceRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
uuid: controlDeviceDto.deviceUuid,
|
uuid: deviceUuid,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -183,7 +215,10 @@ export class DeviceService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new HttpException('Device Not Found', HttpStatus.NOT_FOUND);
|
throw new HttpException(
|
||||||
|
error.message || 'Device Not Found',
|
||||||
|
error.status || HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async controlDeviceTuya(
|
async controlDeviceTuya(
|
||||||
@ -211,12 +246,18 @@ export class DeviceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDeviceDetailsByDeviceId(deviceUuid: string) {
|
async getDeviceDetailsByDeviceId(deviceUuid: string, userUuid: string) {
|
||||||
try {
|
try {
|
||||||
|
const userDevicePermission = await this.getUserDevicePermission(
|
||||||
|
userUuid,
|
||||||
|
deviceUuid,
|
||||||
|
);
|
||||||
|
|
||||||
const deviceDetails = await this.deviceRepository.findOne({
|
const deviceDetails = await this.deviceRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
uuid: deviceUuid,
|
uuid: deviceUuid,
|
||||||
},
|
},
|
||||||
|
relations: ['productDevice'],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!deviceDetails) {
|
if (!deviceDetails) {
|
||||||
@ -232,9 +273,13 @@ export class DeviceService {
|
|||||||
uuid: deviceDetails.uuid,
|
uuid: deviceDetails.uuid,
|
||||||
productUuid: deviceDetails.productDevice.uuid,
|
productUuid: deviceDetails.productDevice.uuid,
|
||||||
productType: deviceDetails.productDevice.prodType,
|
productType: deviceDetails.productDevice.prodType,
|
||||||
|
permissionType: userDevicePermission,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new HttpException('Device Not Found', HttpStatus.NOT_FOUND);
|
throw new HttpException(
|
||||||
|
error.message || 'Device Not Found',
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async getDeviceDetailsByDeviceIdTuya(
|
async getDeviceDetailsByDeviceIdTuya(
|
||||||
@ -257,6 +302,7 @@ export class DeviceService {
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { productName, productId, ...rest } = camelCaseResponse.result;
|
const { productName, productId, ...rest } = camelCaseResponse.result;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...rest,
|
...rest,
|
||||||
productUuid: product.uuid,
|
productUuid: product.uuid,
|
||||||
@ -370,4 +416,13 @@ export class DeviceService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private async getUserDevicePermission(userUuid: string, deviceUuid: string) {
|
||||||
|
const device = await this.deviceRepository.findOne({
|
||||||
|
where: {
|
||||||
|
uuid: deviceUuid,
|
||||||
|
},
|
||||||
|
relations: ['permission', 'permission.permissionType'],
|
||||||
|
});
|
||||||
|
return device.permission[0].permissionType.type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
|
||||||
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
|
|
||||||
import { DeviceUserTypeRepository } from '@app/common/modules/device/repositories';
|
|
||||||
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
|
|
||||||
import {
|
|
||||||
Injectable,
|
|
||||||
CanActivate,
|
|
||||||
HttpStatus,
|
|
||||||
ExecutionContext,
|
|
||||||
BadRequestException,
|
|
||||||
applyDecorators,
|
|
||||||
SetMetadata,
|
|
||||||
UseGuards,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { Reflector } from '@nestjs/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class DevicePermissionGuard implements CanActivate {
|
|
||||||
constructor(
|
|
||||||
private reflector: Reflector,
|
|
||||||
private readonly deviceUserTypeRepository: DeviceUserTypeRepository,
|
|
||||||
private readonly permissionTypeRepository: PermissionTypeRepository,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
||||||
const req = context.switchToHttp().getRequest();
|
|
||||||
try {
|
|
||||||
const { deviceId } = req.headers;
|
|
||||||
const userId = req.user.uuid;
|
|
||||||
|
|
||||||
const requirePermission =
|
|
||||||
this.reflector.getAllAndOverride<PermissionType>('permission', [
|
|
||||||
context.getHandler(),
|
|
||||||
context.getClass(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!requirePermission) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
await this.checkDevicePermission(deviceId, userId, requirePermission);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
this.handleGuardError(error, context);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async checkDevicePermission(
|
|
||||||
deviceId: string,
|
|
||||||
userId: string,
|
|
||||||
requirePermission,
|
|
||||||
) {
|
|
||||||
const [userPermissionDetails, permissionDetails] = await Promise.all([
|
|
||||||
this.deviceUserTypeRepository.findOne({
|
|
||||||
where: { deviceUuid: deviceId, userUuid: userId },
|
|
||||||
}),
|
|
||||||
this.permissionTypeRepository.findOne({
|
|
||||||
where: {
|
|
||||||
type: requirePermission,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
if (!userPermissionDetails) {
|
|
||||||
throw new BadRequestException('User Permission Details Not Found');
|
|
||||||
}
|
|
||||||
if (userPermissionDetails.permissionTypeUuid !== permissionDetails.uuid) {
|
|
||||||
throw new BadRequestException(
|
|
||||||
`User Does not have a ${requirePermission}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleGuardError(error: Error, context: ExecutionContext) {
|
|
||||||
const response = context.switchToHttp().getResponse();
|
|
||||||
console.error(error);
|
|
||||||
|
|
||||||
if (error instanceof BadRequestException) {
|
|
||||||
response
|
|
||||||
.status(HttpStatus.BAD_REQUEST)
|
|
||||||
.json({ statusCode: HttpStatus.BAD_REQUEST, message: error.message });
|
|
||||||
} else {
|
|
||||||
response.status(HttpStatus.NOT_FOUND).json({
|
|
||||||
statusCode: HttpStatus.NOT_FOUND,
|
|
||||||
message: 'User Permission not found',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function AuthGuardWithRoles(permission?: string) {
|
|
||||||
return applyDecorators(
|
|
||||||
SetMetadata('permission', permission),
|
|
||||||
UseGuards(JwtAuthGuard),
|
|
||||||
UseGuards(DevicePermissionGuard),
|
|
||||||
);
|
|
||||||
}
|
|
92
src/guards/user.device.controllable.permission.guard.ts
Normal file
92
src/guards/user.device.controllable.permission.guard.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import {
|
||||||
|
CanActivate,
|
||||||
|
ExecutionContext,
|
||||||
|
Injectable,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { BadRequestException, NotFoundException } from '@nestjs/common';
|
||||||
|
import { UserRepository } from '@app/common/modules/user/repositories';
|
||||||
|
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||||
|
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CheckUserHaveControllablePermission implements CanActivate {
|
||||||
|
constructor(
|
||||||
|
private readonly deviceRepository: DeviceRepository,
|
||||||
|
private readonly userRepository: UserRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
|
const req = context.switchToHttp().getRequest();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
|
const { deviceUuid } = req.params;
|
||||||
|
|
||||||
|
const userIsFound = await this.checkUserIsFound(userUuid);
|
||||||
|
if (!userIsFound) {
|
||||||
|
throw new NotFoundException('User not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const userDevicePermission = await this.checkUserDevicePermission(
|
||||||
|
userUuid,
|
||||||
|
deviceUuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (userDevicePermission === PermissionType.CONTROLLABLE) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException(
|
||||||
|
'You do not have controllable access to this device',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.handleGuardError(error, context);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async checkUserIsFound(userUuid: string) {
|
||||||
|
const userData = await this.userRepository.findOne({
|
||||||
|
where: { uuid: userUuid },
|
||||||
|
});
|
||||||
|
return !!userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async checkUserDevicePermission(
|
||||||
|
userUuid: string,
|
||||||
|
deviceUuid: string,
|
||||||
|
): Promise<string> {
|
||||||
|
const device = await this.deviceRepository.findOne({
|
||||||
|
where: { uuid: deviceUuid, permission: { userUuid: userUuid } },
|
||||||
|
relations: ['permission', 'permission.permissionType'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!device) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
'You do not have controllable access to this device',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return device.permission[0].permissionType.type; // Assuming permissionType is a string
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleGuardError(error: Error, context: ExecutionContext) {
|
||||||
|
const response = context.switchToHttp().getResponse();
|
||||||
|
if (error instanceof NotFoundException) {
|
||||||
|
response
|
||||||
|
.status(HttpStatus.NOT_FOUND)
|
||||||
|
.json({ statusCode: HttpStatus.NOT_FOUND, message: error.message });
|
||||||
|
} else if (error instanceof BadRequestException) {
|
||||||
|
response.status(HttpStatus.BAD_REQUEST).json({
|
||||||
|
statusCode: HttpStatus.BAD_REQUEST,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
response.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
|
||||||
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
91
src/guards/user.device.permission.guard.ts
Normal file
91
src/guards/user.device.permission.guard.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import {
|
||||||
|
CanActivate,
|
||||||
|
ExecutionContext,
|
||||||
|
Injectable,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { BadRequestException, NotFoundException } from '@nestjs/common';
|
||||||
|
import { UserRepository } from '@app/common/modules/user/repositories';
|
||||||
|
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||||
|
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CheckUserHavePermission implements CanActivate {
|
||||||
|
constructor(
|
||||||
|
private readonly deviceRepository: DeviceRepository,
|
||||||
|
private readonly userRepository: UserRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
|
const req = context.switchToHttp().getRequest();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userUuid = req.user.uuid;
|
||||||
|
const { deviceUuid } = req.params;
|
||||||
|
|
||||||
|
const userIsFound = await this.checkUserIsFound(userUuid);
|
||||||
|
if (!userIsFound) {
|
||||||
|
throw new NotFoundException('User not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const userDevicePermission = await this.checkUserDevicePermission(
|
||||||
|
userUuid,
|
||||||
|
deviceUuid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
userDevicePermission === PermissionType.READ ||
|
||||||
|
userDevicePermission === PermissionType.CONTROLLABLE
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException('You do not have access to this device');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.handleGuardError(error, context);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async checkUserIsFound(userUuid: string) {
|
||||||
|
const userData = await this.userRepository.findOne({
|
||||||
|
where: { uuid: userUuid },
|
||||||
|
});
|
||||||
|
return !!userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async checkUserDevicePermission(
|
||||||
|
userUuid: string,
|
||||||
|
deviceUuid: string,
|
||||||
|
): Promise<string> {
|
||||||
|
const device = await this.deviceRepository.findOne({
|
||||||
|
where: { uuid: deviceUuid, permission: { userUuid: userUuid } },
|
||||||
|
relations: ['permission', 'permission.permissionType'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!device) {
|
||||||
|
throw new BadRequestException('You do not have access to this device');
|
||||||
|
}
|
||||||
|
|
||||||
|
return device.permission[0].permissionType.type; // Assuming permissionType is a string
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleGuardError(error: Error, context: ExecutionContext) {
|
||||||
|
const response = context.switchToHttp().getResponse();
|
||||||
|
if (error instanceof NotFoundException) {
|
||||||
|
response
|
||||||
|
.status(HttpStatus.NOT_FOUND)
|
||||||
|
.json({ statusCode: HttpStatus.NOT_FOUND, message: error.message });
|
||||||
|
} else if (error instanceof BadRequestException) {
|
||||||
|
response.status(HttpStatus.BAD_REQUEST).json({
|
||||||
|
statusCode: HttpStatus.BAD_REQUEST,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
response.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
|
||||||
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export * from './user-device-permission.controller';
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
|
Delete,
|
||||||
Get,
|
Get,
|
||||||
|
HttpException,
|
||||||
HttpStatus,
|
HttpStatus,
|
||||||
Param,
|
Param,
|
||||||
Post,
|
Post,
|
||||||
@ -40,40 +42,45 @@ export class UserDevicePermissionController {
|
|||||||
message: 'User Permission for Devices Added Successfully',
|
message: 'User Permission for Devices Added Successfully',
|
||||||
data: addDetails,
|
data: addDetails,
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error(err);
|
throw new HttpException(
|
||||||
|
error.message || 'Internal server error',
|
||||||
|
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Put('edit/:userId')
|
@Put('edit/:devicePermissionUuid')
|
||||||
async editDevicePermission(
|
async editDevicePermission(
|
||||||
@Param('userId') userId: string,
|
@Param('devicePermissionUuid') devicePermissionUuid: string,
|
||||||
@Body() userDevicePermissionEditDto: UserDevicePermissionEditDto,
|
@Body() userDevicePermissionEditDto: UserDevicePermissionEditDto,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
await this.userDevicePermissionService.editUserPermission(
|
await this.userDevicePermissionService.editUserPermission(
|
||||||
userId,
|
devicePermissionUuid,
|
||||||
userDevicePermissionEditDto,
|
userDevicePermissionEditDto,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
statusCode: HttpStatus.OK,
|
statusCode: HttpStatus.OK,
|
||||||
message: 'User Permission for Devices Updated Successfully',
|
message: 'User Permission for Devices Updated Successfully',
|
||||||
data: {},
|
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
throw new Error(err);
|
throw new HttpException(
|
||||||
|
error.message || 'Internal server error',
|
||||||
|
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Get('list')
|
@Get(':deviceUuid/list')
|
||||||
async fetchDevicePermission() {
|
async fetchDevicePermission(@Param('deviceUuid') deviceUuid: string) {
|
||||||
try {
|
try {
|
||||||
const deviceDetails =
|
const deviceDetails =
|
||||||
await this.userDevicePermissionService.fetchuserPermission();
|
await this.userDevicePermissionService.fetchUserPermission(deviceUuid);
|
||||||
return {
|
return {
|
||||||
statusCode: HttpStatus.OK,
|
statusCode: HttpStatus.OK,
|
||||||
message: 'Device Details fetched Successfully',
|
message: 'Device Details fetched Successfully',
|
||||||
@ -83,4 +90,25 @@ export class UserDevicePermissionController {
|
|||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Delete(':devicePermissionUuid')
|
||||||
|
async deleteDevicePermission(
|
||||||
|
@Param('devicePermissionUuid') devicePermissionUuid: string,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
await this.userDevicePermissionService.deleteDevicePermission(
|
||||||
|
devicePermissionUuid,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
statusCode: HttpStatus.OK,
|
||||||
|
message: 'User Permission for Devices Deleted Successfully',
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Internal server error',
|
||||||
|
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
export * from './user-device-permission.add.dto';
|
||||||
|
export * from './user-device-permission.edit.dto';
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
|
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsNotEmpty, IsString } from 'class-validator';
|
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class UserDevicePermissionAddDto {
|
export class UserDevicePermissionAddDto {
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'user id',
|
description: 'user uuid',
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
userId: string;
|
userUuid: string;
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'permission type id',
|
description: 'permission type',
|
||||||
|
enum: PermissionType,
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
@IsString()
|
@IsEnum(PermissionType)
|
||||||
@IsNotEmpty()
|
permissionType: PermissionType;
|
||||||
permissionTypeId: string;
|
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'device id',
|
description: 'device uuid',
|
||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
deviceId: string;
|
deviceUuid: string;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
import { OmitType } from '@nestjs/swagger';
|
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
||||||
import { UserDevicePermissionAddDto } from './user-device-permission.add.dto';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsEnum } from 'class-validator';
|
||||||
|
|
||||||
export class UserDevicePermissionEditDto extends OmitType(
|
export class UserDevicePermissionEditDto {
|
||||||
UserDevicePermissionAddDto,
|
@ApiProperty({
|
||||||
['userId'],
|
description: 'permission type',
|
||||||
) {}
|
enum: PermissionType,
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
@IsEnum(PermissionType)
|
||||||
|
permissionType: PermissionType;
|
||||||
|
}
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
export * from './user-device-permission.service';
|
||||||
|
@ -1,36 +1,107 @@
|
|||||||
import { DeviceUserTypeRepository } from '@app/common/modules/device/repositories';
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { UserDevicePermissionAddDto } from '../dtos/user-device-permission.add.dto';
|
import { UserDevicePermissionAddDto } from '../dtos/user-device-permission.add.dto';
|
||||||
import { UserDevicePermissionEditDto } from '../dtos/user-device-permission.edit.dto';
|
import { UserDevicePermissionEditDto } from '../dtos/user-device-permission.edit.dto';
|
||||||
|
import { DeviceUserPermissionRepository } from '@app/common/modules/device-user-permission/repositories';
|
||||||
|
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserDevicePermissionService {
|
export class UserDevicePermissionService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly deviceUserTypeRepository: DeviceUserTypeRepository,
|
private readonly deviceUserPermissionRepository: DeviceUserPermissionRepository,
|
||||||
|
private readonly permissionTypeRepository: PermissionTypeRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async addUserPermission(userDevicePermissionDto: UserDevicePermissionAddDto) {
|
async addUserPermission(userDevicePermissionDto: UserDevicePermissionAddDto) {
|
||||||
return await this.deviceUserTypeRepository.save({
|
try {
|
||||||
userUuid: userDevicePermissionDto.userId,
|
const permissionType = await this.getPermissionType(
|
||||||
deviceUuid: userDevicePermissionDto.deviceId,
|
userDevicePermissionDto.permissionType,
|
||||||
permissionTypeUuid: userDevicePermissionDto.permissionTypeId,
|
);
|
||||||
|
return await this.deviceUserPermissionRepository.save({
|
||||||
|
userUuid: userDevicePermissionDto.userUuid,
|
||||||
|
deviceUuid: userDevicePermissionDto.deviceUuid,
|
||||||
|
permissionType: {
|
||||||
|
uuid: permissionType.uuid,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code === '23505') {
|
||||||
|
throw new HttpException(
|
||||||
|
'This User already belongs to this device',
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Internal Server Error',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async editUserPermission(
|
async editUserPermission(
|
||||||
userId: string,
|
devicePermissionUuid: string,
|
||||||
userDevicePermissionEditDto: UserDevicePermissionEditDto,
|
userDevicePermissionEditDto: UserDevicePermissionEditDto,
|
||||||
) {
|
) {
|
||||||
return await this.deviceUserTypeRepository.update(
|
try {
|
||||||
{ userUuid: userId },
|
const permissionType = await this.getPermissionType(
|
||||||
|
userDevicePermissionEditDto.permissionType,
|
||||||
|
);
|
||||||
|
return await this.deviceUserPermissionRepository.update(
|
||||||
|
{ uuid: devicePermissionUuid },
|
||||||
{
|
{
|
||||||
deviceUuid: userDevicePermissionEditDto.deviceId,
|
permissionType: {
|
||||||
permissionTypeUuid: userDevicePermissionEditDto.permissionTypeId,
|
uuid: permissionType.uuid,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code === '23505') {
|
||||||
|
throw new HttpException(
|
||||||
|
'This User already belongs to this device',
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Internal Server Error',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchuserPermission() {
|
async fetchUserPermission(deviceUuid: string) {
|
||||||
return await this.deviceUserTypeRepository.find();
|
const devicePermissions = await this.deviceUserPermissionRepository.find({
|
||||||
|
where: {
|
||||||
|
deviceUuid: deviceUuid,
|
||||||
|
},
|
||||||
|
relations: ['permissionType', 'user'],
|
||||||
|
});
|
||||||
|
return devicePermissions.map((permission) => {
|
||||||
|
return {
|
||||||
|
uuid: permission.uuid,
|
||||||
|
deviceUuid: permission.deviceUuid,
|
||||||
|
firstName: permission.user.firstName,
|
||||||
|
lastName: permission.user.lastName,
|
||||||
|
email: permission.user.email,
|
||||||
|
permissionType: permission.permissionType.type,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private async getPermissionType(permissionType: string) {
|
||||||
|
return await this.permissionTypeRepository.findOne({
|
||||||
|
where: {
|
||||||
|
type: permissionType,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async deleteDevicePermission(devicePermissionUuid: string) {
|
||||||
|
try {
|
||||||
|
return await this.deviceUserPermissionRepository.delete({
|
||||||
|
uuid: devicePermissionUuid,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(
|
||||||
|
error.message || 'Internal Server Error',
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { DeviceRepositoryModule } from '@app/common/modules/device';
|
import { DeviceRepositoryModule } from '@app/common/modules/device';
|
||||||
import {
|
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||||
DeviceRepository,
|
|
||||||
DeviceUserTypeRepository,
|
|
||||||
} from '@app/common/modules/device/repositories';
|
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
import { UserDevicePermissionService } from './services/user-device-permission.service';
|
import { UserDevicePermissionService } from './services/user-device-permission.service';
|
||||||
import { UserDevicePermissionController } from './controllers/user-device-permission.controller';
|
import { UserDevicePermissionController } from './controllers/user-device-permission.controller';
|
||||||
|
import { DeviceUserPermissionRepository } from '@app/common/modules/device-user-permission/repositories';
|
||||||
|
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ConfigModule, DeviceRepositoryModule],
|
imports: [ConfigModule, DeviceRepositoryModule],
|
||||||
controllers: [UserDevicePermissionController],
|
controllers: [UserDevicePermissionController],
|
||||||
providers: [
|
providers: [
|
||||||
DeviceUserTypeRepository,
|
DeviceUserPermissionRepository,
|
||||||
|
PermissionTypeRepository,
|
||||||
DeviceRepository,
|
DeviceRepository,
|
||||||
UserDevicePermissionService,
|
UserDevicePermissionService,
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user