import {PERMISSIONS} from "@/constants/userPermissions"; import {app, adminApp} from "@/firebase"; import {Group, 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"; import {getPermissions, getPermissionDocs} from "@/utils/permissions.be"; 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; if (user.type === "corporate" && (targetUser.type === "student" || targetUser.type === "teacher")) { res.json({ok: true}); const userParticipantGroup = await getDocs(query(collection(db, "groups"), where("participants", "array-contains", id))); await Promise.all([ ...userParticipantGroup.docs .filter((x) => (x.data() as Group).admin === user.id) .map( async (x) => await setDoc( x.ref, { participants: x.data().participants.filter((y: string) => y !== id), }, {merge: true}, ), ), ]); return; } const permission = PERMISSIONS.deleteUser[targetUser.type]; if (!permission.list.includes(user.type)) { res.status(403).json({ok: false}); return; } res.json({ok: true}); await auth.deleteUser(id); await deleteDoc(doc(db, "users", id)); 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}, ), ), ]); } 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; await setDoc(docUser.ref, {lastLogin: new Date().toISOString()}, {merge: true}); req.session.user = { ...user, id: req.session.user.id, lastLogin: new Date(), }; await req.session.save(); res.json({...user, id: req.session.user.id}); } else { res.status(401).json(undefined); } }