Skip to content

Commit 61499b0

Browse files
authored
Merge pull request #57 from CS3219-AY2324S1/53-create-delete-button-for-user-to-delete-account
add delete function for userservice, remove account for authservice
2 parents d68ba36 + cf3e643 commit 61499b0

File tree

12 files changed

+177
-20
lines changed

12 files changed

+177
-20
lines changed

AuthService/src/auth/auth.controller.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Request, Response } from "express";
2-
import { signUp, login, logout } from "./auth.service";
2+
import { signUp, login, logout, removeUser } from "./auth.service";
33

44
export async function handleSignUp(req: Request, res: Response) {
55
try {
@@ -35,3 +35,14 @@ export async function handleLogout(req: Request, res: Response) {
3535
res.status(500).send(error);
3636
}
3737
}
38+
39+
export async function handleDelete(req: Request, res: Response) {
40+
try {
41+
console.log(`deleting user`);
42+
await removeUser();
43+
res.status(200).send();
44+
} catch (error) {
45+
console.error(error);
46+
res.status(500).send(error);
47+
}
48+
}

AuthService/src/auth/auth.service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
signInWithEmailAndPassword,
66
signOut,
77
UserCredential,
8+
deleteUser,
89
} from "firebase/auth";
910
import { firebaseConfig } from "../firebase/firebase.config";
1011

@@ -51,3 +52,14 @@ export async function logout(): Promise<void> {
5152
return Promise.reject(error);
5253
}
5354
}
55+
56+
export async function removeUser(): Promise<void> {
57+
try {
58+
if (auth.currentUser) {
59+
await deleteUser(auth.currentUser);
60+
}
61+
return Promise.resolve();
62+
} catch (error) {
63+
return Promise.reject(error);
64+
}
65+
}

AuthService/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
handleLogin,
55
handleLogout,
66
handleSignUp,
7+
handleDelete
78
} from "./auth/auth.controller";
89
// import { Socket, Server } from 'socket.io';
910
// import { initializeApp } from 'firebase/app';
@@ -24,6 +25,7 @@ app.get("/", (req, res) => {
2425
app.post("/signup", handleSignUp);
2526
app.post("/login", handleLogin);
2627
app.delete("/logout", handleLogout);
28+
app.delete("/delete", handleDelete);
2729

2830

2931

UserService/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import cors from "cors";
66
// import { firebaseConfig } from "./firebase/firebase.config";
77
// import { Socket, Server } from 'socket.io';
88
// import { Server as ServerHttp } from 'http';
9-
import { handleCreateUser, handleGetUser, handleUpdateUser } from "./user/user.controller";
9+
import { handleCreateUser, handleDeleteUser, handleGetUser, handleUpdateUser } from "./user/user.controller";
1010
const app = express();
1111
const port = 3004;
1212
app.use(cors());
@@ -25,7 +25,7 @@ app.get("/", (req, res) => {
2525
app.post("/user", handleCreateUser);
2626
app.get("/user", handleGetUser);
2727
app.put("/user", handleUpdateUser);
28-
28+
app.delete("/user", handleDeleteUser);
2929

3030

3131

UserService/src/user/user.controller.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Request, Response } from "express";
2-
import { createUser, getUser, updateUser } from "./user.service";
2+
import { createUser, delUser, getUser, updateUser } from "./user.service";
33

44
export async function handleCreateUser(req: Request, res: Response) {
55
try {
@@ -45,3 +45,19 @@ export async function handleUpdateUser(req: Request, res: Response) {
4545
res.status(500).send(error);
4646
}
4747
}
48+
49+
export async function handleDeleteUser(req: Request, res: Response) {
50+
try {
51+
const user = req.query;
52+
if (user && typeof(user.email) === "string") {
53+
console.log(`deleting user`);
54+
await delUser(user.email)
55+
res.status(200).send("no params");
56+
} else {
57+
res.status(500).send("no params");
58+
}
59+
} catch (error) {
60+
console.error(error);
61+
res.status(500).send(error);
62+
}
63+
}

UserService/src/user/user.service.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import { initializeApp } from "firebase/app";
2-
import { doc, getDoc, getFirestore, setDoc, updateDoc } from "firebase/firestore";
2+
import { doc, getDoc, getFirestore, setDoc, updateDoc, deleteDoc } from "firebase/firestore";
33
import { firebaseConfig } from "../firebase/firebase.config";
4-
5-
initializeApp(firebaseConfig);
6-
const db = getFirestore();
4+
import { getAuth } from "firebase/auth";
5+
const app = initializeApp(firebaseConfig);
6+
const auth = getAuth(app);
7+
const db = getFirestore(app);
78

89
interface User {
9-
email: string;
10+
email?: string;
1011
name?: string;
1112
year?: string;
1213
major?: string;
13-
role: string;
14-
completed: number;
14+
role?: string;
15+
completed?: number;
1516
}
1617

1718
export async function createUser(email: string): Promise<User> {
@@ -81,4 +82,13 @@ export async function updateUser(email: string, params: any): Promise<User> {
8182
} catch (error) {
8283
return Promise.reject(error);
8384
}
85+
}
86+
87+
export async function delUser(user: string): Promise<null> {
88+
try {
89+
await deleteDoc(doc(db, "users", user));
90+
return null;
91+
} catch (error) {
92+
return Promise.reject(error);
93+
}
8494
}

frontend/src/api/auth/data.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ export const signIn = (params: AuthDTO) =>
99
AuthHttpClient.post<UserCredential>("/login", params);
1010

1111
export const signOut = () => AuthHttpClient.delete("/logout");
12+
13+
export const deleteUser = () => AuthHttpClient.delete("/delete");

frontend/src/api/user/data.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import {UserHttpClient} from "../axios/config";
22
import { UserModel, Values } from "./model";
33

4-
54
export const createUser = (email: string) =>
65
UserHttpClient.post<UserModel>("/user", { email: email });
76

87
export const getUser = (email: string) =>
98
UserHttpClient.get<UserModel>("/user", { params: { email: email } });
109

11-
export const updateUser = (params: Values) =>
12-
UserHttpClient.put<UserModel>("/user", { params });
10+
export const updateUser = (params: Values) =>
11+
UserHttpClient.put<UserModel>("/user", { params });
12+
13+
export const deleteActiveUser = (email: string) =>
14+
UserHttpClient.delete<UserModel>("/user", { params: {email: email } });

frontend/src/auth/auth.context.tsx

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
useState,
88
} from "react";
99
import { User } from "firebase/auth";
10-
import { registerUser, signIn, signOut } from "../api/auth";
10+
import { deleteUser, registerUser, signIn, signOut } from "../api/auth";
1111
import { useLocalStorage } from "./useLocalStorage";
1212
import { useNavigate } from "react-router-dom";
1313
import { AxiosError } from "axios";
@@ -16,10 +16,12 @@ import { createUser, getUser, UserModel } from "../api/user";
1616
interface AuthContextData {
1717
user: UserModel | undefined;
1818
setUser: any | undefined,
19+
activeUser: User | undefined;
1920
error: string;
2021
signUp: (email: string, password: string) => void;
2122
login: (email: string, password: string) => void;
2223
logout: () => void;
24+
removeAccount: () => void;
2325
}
2426

2527
interface AuthContextProviderProps {
@@ -29,15 +31,18 @@ interface AuthContextProviderProps {
2931
const AuthContext = createContext<AuthContextData>({
3032
user: undefined,
3133
setUser: undefined,
34+
activeUser: undefined,
3235
error: "",
3336
signUp: (email: string, password: string) => undefined,
3437
login: (email: string, password: string) => undefined,
3538
logout: () => undefined,
39+
removeAccount: () => undefined
3640
});
3741

3842
export function AuthContextProvider({ children }: AuthContextProviderProps) {
3943
const navigate = useNavigate();
4044
const [user, setUser] = useLocalStorage("user", undefined);
45+
const [activeUser, setActiveUser] = useState<User>();
4146
const [error, setError] = useState<string>("");
4247

4348
const signUp = useCallback(
@@ -52,6 +57,7 @@ export function AuthContextProvider({ children }: AuthContextProviderProps) {
5257
throw new Error("user returned without email");
5358
}
5459
const fetchedUser = await createUser(u.email);
60+
setActiveUser(u)
5561
setUser(fetchedUser.data);
5662
} catch (e) {
5763
if (e instanceof AxiosError && e.response) {
@@ -72,9 +78,8 @@ export function AuthContextProvider({ children }: AuthContextProviderProps) {
7278
if (!u.email) {
7379
throw new Error("user returned without email");
7480
}
75-
console.log(u.email);
81+
setActiveUser(u)
7682
const fetchedUser = await getUser(u.email);
77-
console.log(fetchedUser.data);
7883
setUser(fetchedUser.data);
7984
navigate("/home", { replace: true });
8085
} catch (e) {
@@ -92,6 +97,24 @@ export function AuthContextProvider({ children }: AuthContextProviderProps) {
9297
try {
9398
await signOut();
9499
setUser(undefined);
100+
setActiveUser(undefined)
101+
navigate("/", { replace: true });
102+
} catch (e) {
103+
if (e instanceof AxiosError && e.response) {
104+
setError(e.response.data.code);
105+
} else if (e instanceof Error) {
106+
setError(e.message);
107+
}
108+
}
109+
}, [setUser, navigate]);
110+
111+
const removeAccount = useCallback(async () => {
112+
try {
113+
if (activeUser) {
114+
await deleteUser();
115+
}
116+
setUser(undefined);
117+
setActiveUser(undefined)
95118
navigate("/", { replace: true });
96119
} catch (e) {
97120
if (e instanceof AxiosError && e.response) {
@@ -103,8 +126,8 @@ export function AuthContextProvider({ children }: AuthContextProviderProps) {
103126
}, [setUser, navigate]);
104127

105128
const authContextProviderValue = useMemo(
106-
() => ({ user, setUser, error, signUp, login, logout }),
107-
[user, setUser, error, signUp, login, logout]
129+
() => ({ user, setUser, activeUser, error, signUp, login, logout, removeAccount }),
130+
[user, setUser, activeUser, error, signUp, login, logout, removeAccount]
108131
);
109132

110133
return (
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as React from 'react';
2+
import { Box } from "@mui/material";
3+
import Button from '@mui/material/Button';
4+
import { useNavigate } from 'react-router-dom'; // Import useNavigate for redirection
5+
import { useAuth } from '../../auth/auth.context';
6+
import { deleteActiveUser } from '../../api/user';
7+
// import socket from './socket';
8+
9+
const style = {
10+
position: 'absolute' as 'absolute',
11+
top: '50%',
12+
left: '50%',
13+
transform: 'translate(-50%, -50%)',
14+
width: '50%',
15+
display: 'flex-wrap',
16+
maxHeight: '60%',
17+
justifyContent: "center",
18+
textAlign: "center",
19+
bgcolor: 'background.paper',
20+
border: '2px solid #000',
21+
boxShadow: 24,
22+
overflow: 'auto',
23+
p: 4,
24+
};
25+
26+
const AccountDeletionForm = React.forwardRef(function AccountDeletionForm() {
27+
const { activeUser, removeAccount } = useAuth();
28+
29+
const handleDelete = async () => {
30+
try {
31+
if (activeUser?.email) {
32+
const res = await deleteActiveUser(activeUser.email);
33+
const res2 = await removeAccount();
34+
}
35+
} catch (e) {
36+
console.log(e)
37+
}
38+
};
39+
40+
return (
41+
<Box sx={style}>
42+
<h2><center>Are you sure you want to delete your account?</center></h2>
43+
<h4><center>This action cannot be reversed.</center></h4>
44+
<Button sx={{ mt: '5%' }} variant="contained" onClick={handleDelete}>
45+
Confirm
46+
</Button>
47+
</Box>
48+
);
49+
});
50+
51+
export default AccountDeletionForm;

0 commit comments

Comments
 (0)