import type {NextApiRequest, NextApiResponse} from "next"; import {app} from "@/firebase"; import {getFirestore, setDoc, doc, query, collection, where, getDocs, getDoc, deleteDoc, limit, updateDoc} from "firebase/firestore"; import {withIronSessionApiRoute} from "iron-session/next"; import {sessionOptions} from "@/lib/session"; import {v4} from "uuid"; import {CorporateUser, Group} from "@/interfaces/user"; import {createUserWithEmailAndPassword, getAuth} from "firebase/auth"; import ShortUniqueId from "short-unique-id"; import {getUserCorporate} from "@/utils/groups.be"; const DEFAULT_DESIRED_LEVELS = { reading: 9, listening: 9, writing: 9, speaking: 9, }; const DEFAULT_LEVELS = { reading: 0, listening: 0, writing: 0, speaking: 0, }; const auth = getAuth(app); const db = getFirestore(app); export default withIronSessionApiRoute(handler, sessionOptions); async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method === "POST") return post(req, res); return res.status(404).json({ok: false}); } async function post(req: NextApiRequest, res: NextApiResponse) { const maker = req.session.user; if (!maker) { return res.status(401).json({ok: false, reason: "You must be logged in to make user!"}); } const corporateCorporate = await getUserCorporate(maker.id); const {email, passport_id, password, type, groupID, expiryDate, corporate} = req.body as { email: string; password?: string; passport_id: string; type: string; groupID?: string; corporate?: string; expiryDate: null | Date; }; // cleaning data delete req.body.passport_id; delete req.body.groupID; delete req.body.expiryDate; delete req.body.password; delete req.body.corporate; await createUserWithEmailAndPassword(auth, email.toLowerCase(), !!password ? password : passport_id) .then(async (userCredentials) => { const userId = userCredentials.user.uid; const profilePicture = !corporateCorporate ? "/defaultAvatar.png" : corporateCorporate.profilePicture; const user = { ...req.body, bio: "", type: type, focus: "academic", status: "active", desiredLevels: DEFAULT_DESIRED_LEVELS, profilePicture, levels: DEFAULT_LEVELS, isFirstLogin: false, isVerified: true, registrationDate: new Date(), subscriptionExpirationDate: expiryDate || null, ...((maker.type === "corporate" || maker.type === "mastercorporate") && type === "corporate" ? { corporateInformation: { companyInformation: { name: maker.corporateInformation?.companyInformation?.name || "N/A", userAmount: 0, }, }, } : {}), }; const uid = new ShortUniqueId(); const code = uid.randomUUID(6); await setDoc(doc(db, "users", userId), user); await setDoc(doc(db, "codes", code), { code, creator: maker.id, expiryDate, type, creationDate: new Date(), userId, email: email.toLowerCase(), name: req.body.name, ...(!!passport_id ? {passport_id} : {}), }); if (type === "corporate") { const defaultTeachersGroup: Group = { admin: userId, id: v4(), name: "Teachers", participants: [], disableEditing: true, }; const defaultStudentsGroup: Group = { admin: userId, id: v4(), name: "Students", participants: [], disableEditing: true, }; const defaultCorporateGroup: Group = { admin: userId, id: v4(), name: "Corporate", participants: [], disableEditing: true, }; await setDoc(doc(db, "groups", defaultTeachersGroup.id), defaultTeachersGroup); await setDoc(doc(db, "groups", defaultStudentsGroup.id), defaultStudentsGroup); await setDoc(doc(db, "groups", defaultCorporateGroup.id), defaultCorporateGroup); } if (!!corporate) { const corporateQ = query(collection(db, "users"), where("email", "==", corporate.trim().toLowerCase())); const corporateSnapshot = await getDocs(corporateQ); if (!corporateSnapshot.empty) { const corporateUser = {...corporateSnapshot.docs[0].data(), id: corporateSnapshot.docs[0].id} as CorporateUser; await setDoc(doc(db, "codes", code), {creator: corporateUser.id}, {merge: true}); const q = query( collection(db, "groups"), where("admin", "==", corporateUser.id), where("name", "==", type === "student" ? "Students" : "Teachers"), limit(1), ); const snapshot = await getDocs(q); if (!snapshot.empty) { const doc = snapshot.docs[0]; const participants: string[] = doc.get("participants"); if (!participants.includes(userId)) { await updateDoc(doc.ref, { participants: [...participants, userId], }); } } else { const defaultGroup: Group = { admin: corporateUser.id, id: v4(), name: type === "student" ? "Students" : "Teachers", participants: [userId], disableEditing: true, }; await setDoc(doc(db, "groups", defaultGroup.id), defaultGroup); } } } if (maker.type === "corporate") { await setDoc(doc(db, "codes", code), {creator: maker.id}, {merge: true}); const q = query( collection(db, "groups"), where("admin", "==", maker.id), where("name", "==", type === "student" ? "Students" : "Teachers"), limit(1), ); const snapshot = await getDocs(q); if (!snapshot.empty) { const doc = snapshot.docs[0]; const participants: string[] = doc.get("participants"); if (!participants.includes(userId)) { await updateDoc(doc.ref, { participants: [...participants, userId], }); } } else { const defaultGroup: Group = { admin: maker.id, id: v4(), name: type === "student" ? "Students" : "Teachers", participants: [userId], disableEditing: true, }; await setDoc(doc(db, "groups", defaultGroup.id), defaultGroup); } } if (!!corporateCorporate && corporateCorporate.type === "mastercorporate" && type === "corporate") { const q = query(collection(db, "groups"), where("admin", "==", corporateCorporate.id), where("name", "==", "corporate"), limit(1)); const snapshot = await getDocs(q); if (!snapshot.empty) { const doc = snapshot.docs[0]; const participants: string[] = doc.get("participants"); if (!participants.includes(userId)) { await updateDoc(doc.ref, { participants: [...participants, userId], }); } } else { const defaultGroup: Group = { admin: corporateCorporate.id, id: v4(), name: "Corporate", participants: [userId], disableEditing: true, }; await setDoc(doc(db, "groups", defaultGroup.id), defaultGroup); } } if (!!groupID) { const groupSnapshot = await getDoc(doc(db, "groups", groupID)); await setDoc(groupSnapshot.ref, {participants: [...groupSnapshot.data()!.participants, userId]}, {merge: true}); } console.log(`Returning - ${email}`); return res.status(200).json({ok: true}); }) .catch((error) => { console.log(`Failing - ${email}`); console.log(error); return res.status(401).json({error}); }); }