Skip to content

Commit

Permalink
Merge pull request #38 from nuuxcode/debug
Browse files Browse the repository at this point in the history
Add delete account, add request to backend, setup backend api
  • Loading branch information
nuuxcode authored Dec 11, 2023
2 parents ff11587 + 6ca068e commit ea91c8d
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 20 deletions.
18 changes: 17 additions & 1 deletion api/src/modules/user/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Controller,
Get,
Post,
Delete,
Put,
UseGuards,
Param,
Expand All @@ -20,7 +21,7 @@ import { UserService } from './user.service';
@ApiTags('users')
@Controller('/users')
export class UserController {
constructor(private userService: UserService) {}
constructor(private userService: UserService) { }

@Get()
@Roles(ROLES_ENUM.ADMIN)
Expand Down Expand Up @@ -48,4 +49,19 @@ export class UserController {
data: userData,
});
}

@Delete('delete/:id')
@Roles(ROLES_ENUM.ADMIN)
@UseGuards(JwtAuthGuard)
async deleteUser(
@Param('id') id: string,
@Body('password') password: string,
): Promise<{ message: string }> {
const deletedUser = await this.userService.deleteUser(
{ id: Number(id) },
password,
);

return { message: 'User deleted' };
}
}
29 changes: 25 additions & 4 deletions api/src/modules/user/user.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Prisma, User } from '@prisma/client';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Injectable, UnauthorizedException, NotFoundException, BadRequestException } from '@nestjs/common';
import { AuthHelpers } from '../../shared/helpers/auth.helpers';
import { PrismaService } from '../prisma/prisma.service';
import { UpdateUser } from './../auth/auth.dto';
Expand Down Expand Up @@ -57,7 +57,7 @@ export class UserService {
);
if (!isMatch) {
console.log("old password doesn't match")
throw new UnauthorizedException("Old password doesn't match");
throw new BadRequestException("Old password doesn't match");
}
data.password = data.newPassword;
delete data.oldPassword;
Expand All @@ -75,9 +75,30 @@ export class UserService {
return updatedUser;
}

async deleteUser(where: Prisma.UserWhereUniqueInput): Promise<User> {
return this.prisma.user.delete({
async deleteUser(
where: Prisma.UserWhereUniqueInput,
password: string,
): Promise<User> {
const user = await this.prisma.user.findUnique({
where,
});
console.log("user found:", user)
if (!user) {
throw new NotFoundException('User not found');
}

const isMatch = await AuthHelpers.verify(password, user.password);

if (!isMatch) {
throw new UnauthorizedException('Incorrect password');
}

const deleteduser = await this.prisma.user.delete({
where,
});
delete deleteduser.password;
console.log("user deleted:", deleteduser)
return deleteduser;
}

}
Original file line number Diff line number Diff line change
@@ -1,34 +1,76 @@
import { ViewIcon, ViewOffIcon } from "@chakra-ui/icons";
import {
AlertDialog,
AlertDialogBody,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogOverlay,
Button,
FormControl,
FormErrorMessage,
FormLabel,
Input,
InputGroup,
InputRightElement,
Button,
useToast,
AlertDialog,
AlertDialogBody,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogOverlay,
useDisclosure,
} from "@chakra-ui/react";
import React, { useState } from "react";
import axios from "../../../apis/axios";
import { useAuth } from "../../../hooks/useAuth";

export default function DeleteUserForm({
className = "",
}: {
interface DeleteUserFormProps {
className?: string;
}) {
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = React.useRef<HTMLButtonElement>(null);
}

const DeleteUserForm: React.FC<DeleteUserFormProps> = ({
className = "",
}) => {
const { user, logout } = useAuth();
const [showPassword, setShowPassword] = useState(false);
const [password, setPassword] = useState("");
const [errPassword, setErrPassword] = useState(false);
const toast = useToast({ position: "top" });
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = React.useRef<HTMLButtonElement>(null);
const [errMsg, setErrMsg] = useState("");

const handleClick = async () => {
setErrPassword(false);

try {
const response = await axios.delete(`/users/delete/${user?.id}`, { data: { password }, withCredentials: true, });
// Handle success response
console.log(response);
toast({
title: "Account deleted",
description: "Your account has been deleted.",
status: "success",
duration: 5000,
isClosable: true,
});
logout();
} catch (error: any) {
console.log(error);
let errorMessage = error?.response?.data?.message;
if (typeof errorMessage === "string") {
errorMessage = error?.response?.data?.message;
setErrMsg(errorMessage);
} else {
errorMessage = error?.response?.data?.message.join(", ");
setErrMsg(errorMessage);
}
toast({
title: "Error",
description: errorMessage || "Something went wrong.",
status: "error",
duration: 5000,
isClosable: true,
});
}
};

return (
<section className={`p-5 space-y-6 ${className}`}>
<header>
Expand Down Expand Up @@ -95,7 +137,7 @@ export default function DeleteUserForm({
<Button ref={cancelRef} onClick={onClose}>
Cancel
</Button>
<Button colorScheme="red" onClick={onClose} ml={3}>
<Button colorScheme="red" onClick={handleClick} ml={3}>
Delete
</Button>
</AlertDialogFooter>
Expand All @@ -105,4 +147,6 @@ export default function DeleteUserForm({
</AlertDialog>
</section>
);
}
};

export default DeleteUserForm;

0 comments on commit ea91c8d

Please sign in to comment.