import {PERMISSIONS} from "@/constants/userPermissions"; import {app, adminApp} from "@/firebase"; import {User} from "@/interfaces/user"; import {sessionOptions} from "@/lib/session"; import {collection, deleteDoc, doc, getDoc, getDocs, getFirestore, query, setDoc, where} from "firebase/firestore"; import {getAuth} from "firebase-admin/auth"; import {withIronSessionApiRoute} from "iron-session/next"; import {NextApiRequest, NextApiResponse} from "next"; const db = getFirestore(app); const auth = getAuth(adminApp); export default withIronSessionApiRoute(user, sessionOptions); async function user(req: NextApiRequest, res: NextApiResponse) { if (req.method === "GET") return get(req, res); if (req.method === "DELETE") return del(req, res); res.status(404).json(undefined); } async function del(req: NextApiRequest, res: NextApiResponse) { if (!req.session.user) { res.status(401).json({ok: false}); return; } const {id} = req.query as {id: string}; const docUser = await getDoc(doc(db, "users", req.session.user.id)); if (!docUser.exists()) { res.status(401).json({ok: false}); return; } const user = docUser.data() as User; const docTargetUser = await getDoc(doc(db, "users", id)); if (!docTargetUser.exists()) { res.status(404).json({ok: false}); return; } const targetUser = {...docTargetUser.data(), id: docTargetUser.id} as User; const permission = PERMISSIONS.deleteUser[targetUser.type]; if (!permission.includes(user.type)) { res.status(403).json({ok: false}); return; } const userCodeDocs = await getDocs(query(collection(db, "codes"), where("userId", "==", id))); const userParticipantGroup = await getDocs(query(collection(db, "groups"), where("participants", "array-contains", id))); const userGroupAdminDocs = await getDocs(query(collection(db, "groups"), where("admin", "==", id))); const userStatsDocs = await getDocs(query(collection(db, "stats"), where("user", "==", id))); await Promise.all([ ...userCodeDocs.docs.map(async (x) => await deleteDoc(x.ref)), ...userGroupAdminDocs.docs.map(async (x) => await deleteDoc(x.ref)), ...userStatsDocs.docs.map(async (x) => await deleteDoc(x.ref)), ...userParticipantGroup.docs.map( async (x) => await setDoc(x.ref, {participants: x.data().participants.filter((y: string) => y !== id)}, {merge: true}), ), ]); await auth.deleteUser(id); await deleteDoc(doc(db, "users", id)); res.json({ok: true}); } async function get(req: NextApiRequest, res: NextApiResponse) { if (req.session.user) { const docUser = await getDoc(doc(db, "users", req.session.user.id)); if (!docUser.exists()) { res.status(401).json(undefined); return; } const user = docUser.data() as User; req.session.user = {...user, id: req.session.user.id}; await req.session.save(); res.json({...user, id: req.session.user.id}); } else { res.status(401).json(undefined); } }