import {NextApiRequest, NextApiResponse} from "next"; import {createUserWithEmailAndPassword, getAuth} from "firebase/auth"; import {app} from "@/firebase"; import {sessionOptions} from "@/lib/session"; import {withIronSessionApiRoute} from "iron-session/next"; import {getFirestore, doc, setDoc, query, collection, where, getDocs} from "firebase/firestore"; import {CorporateInformation, DemographicInformation, Type} from "@/interfaces/user"; import {addUserToGroupOnCreation} from "@/utils/registration"; import moment from "moment"; const auth = getAuth(app); const db = getFirestore(app); export default withIronSessionApiRoute(register, sessionOptions); const DEFAULT_DESIRED_LEVELS = { reading: 9, listening: 9, writing: 9, speaking: 9, }; const DEFAULT_LEVELS = { reading: 0, listening: 0, writing: 0, speaking: 0, }; async function register(req: NextApiRequest, res: NextApiResponse) { const {type} = req.body as { type: "individual" | "corporate"; }; if (type === "individual") return registerIndividual(req, res); if (type === "corporate") return registerCorporate(req, res); } async function registerIndividual(req: NextApiRequest, res: NextApiResponse) { const {email, passport_id, password, code} = req.body as { email: string; passport_id?: string; password: string; code?: string; }; const codeQuery = query(collection(db, "codes"), where("code", "==", code)); const codeDocs = (await getDocs(codeQuery)).docs.filter((x) => !Object.keys(x.data()).includes("userId")); if (code && code.length > 0 && codeDocs.length === 0) { res.status(400).json({error: "Invalid Code!"}); return; } const codeData = codeDocs.length > 0 ? (codeDocs[0].data() as {code: string; type: Type; creator?: string; expiryDate: Date | null}) : undefined; createUserWithEmailAndPassword(auth, email, password) .then(async (userCredentials) => { const userId = userCredentials.user.uid; delete req.body.password; const user = { ...req.body, desiredLevels: DEFAULT_DESIRED_LEVELS, levels: DEFAULT_LEVELS, bio: "", isFirstLogin: codeData ? codeData.type === "student" : true, focus: "academic", type: email.endsWith("@ecrop.dev") ? "developer" : codeData ? codeData.type : "student", subscriptionExpirationDate: codeData ? codeData.expiryDate : moment().subtract(1, "days").toISOString(), ...(passport_id ? {demographicInformation: {passport_id}} : {}), registrationDate: new Date().toISOString(), status: code ? "active" : "paymentDue", }; await setDoc(doc(db, "users", userId), user); if (codeDocs.length > 0 && codeData) { await setDoc(codeDocs[0].ref, {userId: userId}, {merge: true}); if (codeData.creator) await addUserToGroupOnCreation(userId, codeData.type, codeData.creator); } req.session.user = {...user, id: userId}; await req.session.save(); res.status(200).json({user: {...user, id: userId}}); }) .catch((error) => { console.log(error); res.status(401).json({error}); }); } async function registerCorporate(req: NextApiRequest, res: NextApiResponse) { const {email, password} = req.body as { email: string; password: string; corporateInformation: CorporateInformation; }; createUserWithEmailAndPassword(auth, email, password) .then(async (userCredentials) => { const userId = userCredentials.user.uid; delete req.body.password; const user = { ...req.body, desiredLevels: DEFAULT_DESIRED_LEVELS, levels: DEFAULT_LEVELS, bio: "", isFirstLogin: false, focus: "academic", type: "corporate", subscriptionExpirationDate: req.body.subscriptionExpirationDate || null, status: "paymentDue", registrationDate: new Date().toISOString(), }; await setDoc(doc(db, "users", userId), user); req.session.user = {...user, id: userId}; await req.session.save(); res.status(200).json({user: {...user, id: userId}}); }) .catch((error) => { console.log(error); res.status(401).json({error}); }); }