mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-10 07:07:21 +00:00
task: delete used & its relations
This commit is contained in:
@ -397,6 +397,11 @@ export class ControllerRoute {
|
|||||||
public static readonly DELETE_USER_SUMMARY = 'Delete user by UUID';
|
public static readonly DELETE_USER_SUMMARY = 'Delete user by UUID';
|
||||||
public static readonly DELETE_USER_DESCRIPTION =
|
public static readonly DELETE_USER_DESCRIPTION =
|
||||||
'This endpoint deletes a user identified by their UUID. Accessible only by users with the Super Admin role.';
|
'This endpoint deletes a user identified by their UUID. Accessible only by users with the Super Admin role.';
|
||||||
|
|
||||||
|
public static readonly DELETE_USER_PROFILE_SUMMARY =
|
||||||
|
'Delete user profile by UUID';
|
||||||
|
public static readonly DELETE_USER_PROFILE_DESCRIPTION =
|
||||||
|
'This endpoint deletes a user profile identified by their UUID. Accessible only by users with the Super Admin role.';
|
||||||
public static readonly UPDATE_USER_WEB_AGREEMENT_SUMMARY =
|
public static readonly UPDATE_USER_WEB_AGREEMENT_SUMMARY =
|
||||||
'Update user web agreement by user UUID';
|
'Update user web agreement by user UUID';
|
||||||
public static readonly UPDATE_USER_WEB_AGREEMENT_DESCRIPTION =
|
public static readonly UPDATE_USER_WEB_AGREEMENT_DESCRIPTION =
|
||||||
|
@ -8,14 +8,14 @@ import {
|
|||||||
Unique,
|
Unique,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
|
||||||
import { RoleTypeEntity } from '../../role-type/entities';
|
|
||||||
import { UserStatusEnum } from '@app/common/constants/user-status.enum';
|
|
||||||
import { UserEntity } from '../../user/entities';
|
|
||||||
import { RoleType } from '@app/common/constants/role.type.enum';
|
import { RoleType } from '@app/common/constants/role.type.enum';
|
||||||
import { InviteUserDto, InviteUserSpaceDto } from '../dtos';
|
import { UserStatusEnum } from '@app/common/constants/user-status.enum';
|
||||||
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { ProjectEntity } from '../../project/entities';
|
import { ProjectEntity } from '../../project/entities';
|
||||||
|
import { RoleTypeEntity } from '../../role-type/entities';
|
||||||
import { SpaceEntity } from '../../space/entities/space.entity';
|
import { SpaceEntity } from '../../space/entities/space.entity';
|
||||||
|
import { UserEntity } from '../../user/entities';
|
||||||
|
import { InviteUserDto, InviteUserSpaceDto } from '../dtos';
|
||||||
|
|
||||||
@Entity({ name: 'invite-user' })
|
@Entity({ name: 'invite-user' })
|
||||||
@Unique(['email', 'project'])
|
@Unique(['email', 'project'])
|
||||||
@ -82,7 +82,10 @@ export class InviteUserEntity extends AbstractEntity<InviteUserDto> {
|
|||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
public roleType: RoleTypeEntity;
|
public roleType: RoleTypeEntity;
|
||||||
@OneToOne(() => UserEntity, (user) => user.inviteUser, { nullable: true })
|
@OneToOne(() => UserEntity, (user) => user.inviteUser, {
|
||||||
|
nullable: true,
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
@JoinColumn({ name: 'user_uuid' })
|
@JoinColumn({ name: 'user_uuid' })
|
||||||
user: UserEntity;
|
user: UserEntity;
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
@ -112,7 +115,9 @@ export class InviteUserSpaceEntity extends AbstractEntity<InviteUserSpaceDto> {
|
|||||||
})
|
})
|
||||||
public uuid: string;
|
public uuid: string;
|
||||||
|
|
||||||
@ManyToOne(() => InviteUserEntity, (inviteUser) => inviteUser.spaces)
|
@ManyToOne(() => InviteUserEntity, (inviteUser) => inviteUser.spaces, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
@JoinColumn({ name: 'invite_user_uuid' })
|
@JoinColumn({ name: 'invite_user_uuid' })
|
||||||
public inviteUser: InviteUserEntity;
|
public inviteUser: InviteUserEntity;
|
||||||
|
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
Entity,
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
Unique,
|
Unique,
|
||||||
Index,
|
|
||||||
JoinColumn,
|
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { DeviceDto, DeviceUserPermissionDto } from '../dtos/device.dto';
|
|
||||||
import { ProductEntity } from '../../product/entities';
|
|
||||||
import { UserEntity } from '../../user/entities';
|
|
||||||
import { DeviceNotificationDto } from '../dtos';
|
|
||||||
import { PermissionTypeEntity } from '../../permission/entities';
|
import { PermissionTypeEntity } from '../../permission/entities';
|
||||||
|
import { PowerClampHourlyEntity } from '../../power-clamp/entities/power-clamp.entity';
|
||||||
|
import { PresenceSensorDailyDeviceEntity } from '../../presence-sensor/entities';
|
||||||
|
import { ProductEntity } from '../../product/entities';
|
||||||
import { SceneDeviceEntity } from '../../scene-device/entities';
|
import { SceneDeviceEntity } from '../../scene-device/entities';
|
||||||
import { SpaceEntity } from '../../space/entities/space.entity';
|
import { SpaceEntity } from '../../space/entities/space.entity';
|
||||||
import { SubspaceEntity } from '../../space/entities/subspace/subspace.entity';
|
import { SubspaceEntity } from '../../space/entities/subspace/subspace.entity';
|
||||||
import { NewTagEntity } from '../../tag';
|
import { NewTagEntity } from '../../tag';
|
||||||
import { PowerClampHourlyEntity } from '../../power-clamp/entities/power-clamp.entity';
|
import { UserEntity } from '../../user/entities';
|
||||||
import { PresenceSensorDailyDeviceEntity } from '../../presence-sensor/entities';
|
import { DeviceNotificationDto } from '../dtos';
|
||||||
|
import { DeviceDto, DeviceUserPermissionDto } from '../dtos/device.dto';
|
||||||
|
|
||||||
@Entity({ name: 'device' })
|
@Entity({ name: 'device' })
|
||||||
@Unique(['deviceTuyaUuid'])
|
@Unique(['deviceTuyaUuid'])
|
||||||
@ -111,6 +111,7 @@ export class DeviceNotificationEntity extends AbstractEntity<DeviceNotificationD
|
|||||||
|
|
||||||
@ManyToOne(() => UserEntity, (user) => user.userPermission, {
|
@ManyToOne(() => UserEntity, (user) => user.userPermission, {
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
user: UserEntity;
|
user: UserEntity;
|
||||||
|
|
||||||
@ -149,6 +150,7 @@ export class DeviceUserPermissionEntity extends AbstractEntity<DeviceUserPermiss
|
|||||||
|
|
||||||
@ManyToOne(() => UserEntity, (user) => user.userPermission, {
|
@ManyToOne(() => UserEntity, (user) => user.userPermission, {
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
user: UserEntity;
|
user: UserEntity;
|
||||||
constructor(partial: Partial<DeviceUserPermissionEntity>) {
|
constructor(partial: Partial<DeviceUserPermissionEntity>) {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { defaultProfilePicture } from '@app/common/constants/default.profile.picture';
|
||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
@ -8,27 +9,26 @@ import {
|
|||||||
OneToOne,
|
OneToOne,
|
||||||
Unique,
|
Unique,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
import { OtpType } from '../../../../src/constants/otp-type.enum';
|
||||||
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
|
import { ClientEntity } from '../../client/entities';
|
||||||
|
import {
|
||||||
|
DeviceNotificationEntity,
|
||||||
|
DeviceUserPermissionEntity,
|
||||||
|
} from '../../device/entities';
|
||||||
|
import { InviteUserEntity } from '../../Invite-user/entities';
|
||||||
|
import { ProjectEntity } from '../../project/entities';
|
||||||
|
import { RegionEntity } from '../../region/entities';
|
||||||
|
import { RoleTypeEntity } from '../../role-type/entities';
|
||||||
|
import { SpaceEntity } from '../../space/entities/space.entity';
|
||||||
|
import { TimeZoneEntity } from '../../timezone/entities';
|
||||||
|
import { VisitorPasswordEntity } from '../../visitor-password/entities';
|
||||||
import {
|
import {
|
||||||
UserDto,
|
UserDto,
|
||||||
UserNotificationDto,
|
UserNotificationDto,
|
||||||
UserOtpDto,
|
UserOtpDto,
|
||||||
UserSpaceDto,
|
UserSpaceDto,
|
||||||
} from '../dtos';
|
} from '../dtos';
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
|
||||||
import {
|
|
||||||
DeviceNotificationEntity,
|
|
||||||
DeviceUserPermissionEntity,
|
|
||||||
} from '../../device/entities';
|
|
||||||
import { defaultProfilePicture } from '@app/common/constants/default.profile.picture';
|
|
||||||
import { RegionEntity } from '../../region/entities';
|
|
||||||
import { TimeZoneEntity } from '../../timezone/entities';
|
|
||||||
import { OtpType } from '../../../../src/constants/otp-type.enum';
|
|
||||||
import { RoleTypeEntity } from '../../role-type/entities';
|
|
||||||
import { VisitorPasswordEntity } from '../../visitor-password/entities';
|
|
||||||
import { InviteUserEntity } from '../../Invite-user/entities';
|
|
||||||
import { ProjectEntity } from '../../project/entities';
|
|
||||||
import { SpaceEntity } from '../../space/entities/space.entity';
|
|
||||||
import { ClientEntity } from '../../client/entities';
|
|
||||||
|
|
||||||
@Entity({ name: 'user' })
|
@Entity({ name: 'user' })
|
||||||
export class UserEntity extends AbstractEntity<UserDto> {
|
export class UserEntity extends AbstractEntity<UserDto> {
|
||||||
@ -94,7 +94,9 @@ export class UserEntity extends AbstractEntity<UserDto> {
|
|||||||
@Column({ type: 'timestamp', nullable: true })
|
@Column({ type: 'timestamp', nullable: true })
|
||||||
appAgreementAcceptedAt: Date;
|
appAgreementAcceptedAt: Date;
|
||||||
|
|
||||||
@OneToMany(() => UserSpaceEntity, (userSpace) => userSpace.user)
|
@OneToMany(() => UserSpaceEntity, (userSpace) => userSpace.user, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
userSpaces: UserSpaceEntity[];
|
userSpaces: UserSpaceEntity[];
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
@ -158,6 +160,7 @@ export class UserEntity extends AbstractEntity<UserDto> {
|
|||||||
export class UserNotificationEntity extends AbstractEntity<UserNotificationDto> {
|
export class UserNotificationEntity extends AbstractEntity<UserNotificationDto> {
|
||||||
@ManyToOne(() => UserEntity, (user) => user.roleType, {
|
@ManyToOne(() => UserEntity, (user) => user.roleType, {
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
user: UserEntity;
|
user: UserEntity;
|
||||||
@Column({
|
@Column({
|
||||||
@ -219,7 +222,10 @@ export class UserSpaceEntity extends AbstractEntity<UserSpaceDto> {
|
|||||||
})
|
})
|
||||||
public uuid: string;
|
public uuid: string;
|
||||||
|
|
||||||
@ManyToOne(() => UserEntity, (user) => user.userSpaces, { nullable: false })
|
@ManyToOne(() => UserEntity, (user) => user.userSpaces, {
|
||||||
|
nullable: false,
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
user: UserEntity;
|
user: UserEntity;
|
||||||
|
|
||||||
@ManyToOne(() => SpaceEntity, (space) => space.userSpaces, {
|
@ManyToOne(() => SpaceEntity, (space) => space.userSpaces, {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Column, Entity, ManyToOne, JoinColumn, Index } from 'typeorm';
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
import { VisitorPasswordDto } from '../dtos';
|
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { UserEntity } from '../../user/entities/user.entity';
|
import { UserEntity } from '../../user/entities/user.entity';
|
||||||
|
import { VisitorPasswordDto } from '../dtos';
|
||||||
|
|
||||||
@Entity({ name: 'visitor-password' })
|
@Entity({ name: 'visitor-password' })
|
||||||
@Index('IDX_PASSWORD_TUYA_UUID', ['passwordTuyaUuid'])
|
@Index('IDX_PASSWORD_TUYA_UUID', ['passwordTuyaUuid'])
|
||||||
@ -14,6 +14,7 @@ export class VisitorPasswordEntity extends AbstractEntity<VisitorPasswordDto> {
|
|||||||
|
|
||||||
@ManyToOne(() => UserEntity, (user) => user.visitorPasswords, {
|
@ManyToOne(() => UserEntity, (user) => user.visitorPasswords, {
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
onDelete: 'CASCADE',
|
||||||
})
|
})
|
||||||
@JoinColumn({ name: 'authorizer_uuid' })
|
@JoinColumn({ name: 'authorizer_uuid' })
|
||||||
public user: UserEntity;
|
public user: UserEntity;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import { ControllerRoute } from '@app/common/constants/controller-route';
|
||||||
|
import { EnableDisableStatusEnum } from '@app/common/constants/days.enum';
|
||||||
|
import { RoleType } from '@app/common/constants/role.type.enum';
|
||||||
|
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||||
import {
|
import {
|
||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
@ -7,10 +11,12 @@ import {
|
|||||||
Param,
|
Param,
|
||||||
Patch,
|
Patch,
|
||||||
Put,
|
Put,
|
||||||
|
Req,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { UserService } from '../services/user.service';
|
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
|
import { CheckProfilePictureGuard } from 'src/guards/profile.picture.guard';
|
||||||
|
import { SuperAdminRoleGuard } from 'src/guards/super.admin.role.guard';
|
||||||
import { JwtAuthGuard } from '../../../libs/common/src/guards/jwt.auth.guard';
|
import { JwtAuthGuard } from '../../../libs/common/src/guards/jwt.auth.guard';
|
||||||
import {
|
import {
|
||||||
UpdateNameDto,
|
UpdateNameDto,
|
||||||
@ -18,11 +24,7 @@ import {
|
|||||||
UpdateRegionDataDto,
|
UpdateRegionDataDto,
|
||||||
UpdateTimezoneDataDto,
|
UpdateTimezoneDataDto,
|
||||||
} from '../dtos';
|
} from '../dtos';
|
||||||
import { CheckProfilePictureGuard } from 'src/guards/profile.picture.guard';
|
import { UserService } from '../services/user.service';
|
||||||
import { SuperAdminRoleGuard } from 'src/guards/super.admin.role.guard';
|
|
||||||
import { EnableDisableStatusEnum } from '@app/common/constants/days.enum';
|
|
||||||
import { ControllerRoute } from '@app/common/constants/controller-route';
|
|
||||||
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
|
||||||
|
|
||||||
@ApiTags('User Module')
|
@ApiTags('User Module')
|
||||||
@Controller({
|
@Controller({
|
||||||
@ -154,6 +156,32 @@ export class UserController {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Delete('')
|
||||||
|
@ApiOperation({
|
||||||
|
summary: ControllerRoute.USER.ACTIONS.DELETE_USER_PROFILE_SUMMARY,
|
||||||
|
description: ControllerRoute.USER.ACTIONS.DELETE_USER_PROFILE_DESCRIPTION,
|
||||||
|
})
|
||||||
|
async deleteUserProfile(@Req() req: Request) {
|
||||||
|
const userUuid = req['user']?.userUuid;
|
||||||
|
const userRole = req['user']?.role;
|
||||||
|
if (!userUuid || (userRole && userRole == RoleType.SUPER_ADMIN)) {
|
||||||
|
throw {
|
||||||
|
statusCode: HttpStatus.UNAUTHORIZED,
|
||||||
|
message: 'Unauthorized',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await this.userService.deleteUserProfile(userUuid);
|
||||||
|
return {
|
||||||
|
statusCode: HttpStatus.OK,
|
||||||
|
data: {
|
||||||
|
userId: userUuid,
|
||||||
|
},
|
||||||
|
message: 'User deleted successfully',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Patch('agreements/web/:userUuid')
|
@Patch('agreements/web/:userUuid')
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import {
|
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
||||||
UpdateNameDto,
|
import { removeBase64Prefix } from '@app/common/helper/removeBase64Prefix';
|
||||||
UpdateProfilePictureDataDto,
|
import { RegionRepository } from '@app/common/modules/region/repositories';
|
||||||
UpdateRegionDataDto,
|
import { TimeZoneRepository } from '@app/common/modules/timezone/repositories';
|
||||||
UpdateTimezoneDataDto,
|
import { UserEntity } from '@app/common/modules/user/entities';
|
||||||
} from './../dtos/update.user.dto';
|
import { UserRepository } from '@app/common/modules/user/repositories';
|
||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
HttpException,
|
HttpException,
|
||||||
HttpStatus,
|
HttpStatus,
|
||||||
Injectable,
|
Injectable,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { UserRepository } from '@app/common/modules/user/repositories';
|
import {
|
||||||
import { RegionRepository } from '@app/common/modules/region/repositories';
|
UpdateNameDto,
|
||||||
import { TimeZoneRepository } from '@app/common/modules/timezone/repositories';
|
UpdateProfilePictureDataDto,
|
||||||
import { removeBase64Prefix } from '@app/common/helper/removeBase64Prefix';
|
UpdateRegionDataDto,
|
||||||
import { UserEntity } from '@app/common/modules/user/entities';
|
UpdateTimezoneDataDto,
|
||||||
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
} from './../dtos/update.user.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
@ -269,4 +269,12 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
return await this.userRepository.update({ uuid }, { isActive: false });
|
return await this.userRepository.update({ uuid }, { isActive: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteUserProfile(uuid: string) {
|
||||||
|
const user = await this.findOneById(uuid);
|
||||||
|
if (!user) {
|
||||||
|
throw new BadRequestException('User not found');
|
||||||
|
}
|
||||||
|
return this.userRepository.delete({ uuid });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user