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 {Code, CorporateInformation, DemographicInformation, Group, Type} from "@/interfaces/user"; import {addUserToGroupOnCreation} from "@/utils/registration"; import moment from "moment"; import {v4} from "uuid"; import client from "@/lib/mongodb"; const auth = getAuth(app); const db = client.db(process.env.MONGODB_DB); 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 codeDoc = await db.collection("codes").findOne({code}); if (code && code.length > 0 && !!codeDoc) { res.status(400).json({error: "Invalid Code!"}); return; } createUserWithEmailAndPassword(auth, email.toLowerCase(), password) .then(async (userCredentials) => { const userId = userCredentials.user.uid; delete req.body.password; const user = { ...req.body, id: userId, email: email.toLowerCase(), desiredLevels: DEFAULT_DESIRED_LEVELS, levels: DEFAULT_LEVELS, bio: "", isFirstLogin: codeDoc ? codeDoc.type === "student" : true, profilePicture: "/defaultAvatar.png", focus: "academic", type: email.endsWith("@ecrop.dev") ? "developer" : codeDoc ? codeDoc.type : "student", subscriptionExpirationDate: codeDoc ? codeDoc.expiryDate : moment().subtract(1, "days").toISOString(), ...(passport_id ? {demographicInformation: {passport_id}} : {}), registrationDate: new Date().toISOString(), status: code ? "active" : "paymentDue", }; await db.collection("users").insertOne(user); if (!!codeDoc) { await db.collection("codes").updateOne({code: codeDoc.code}, {$set: {userId}}); if (codeDoc.creator) await addUserToGroupOnCreation(userId, codeDoc.type, codeDoc.creator); } req.session.user = user; await req.session.save(); res.status(200).json({user}); }) .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.toLowerCase(), password) .then(async (userCredentials) => { const userId = userCredentials.user.uid; delete req.body.password; const user = { ...req.body, id: userId, email: email.toLowerCase(), 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(), }; 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 db.collection("users").insertOne(user); await db.collection("groups").insertMany([defaultCorporateGroup, defaultStudentsGroup, defaultTeachersGroup]); req.session.user = user; await req.session.save(); res.status(200).json({user}); }) .catch((error) => { console.log(error); res.status(401).json({error}); }); }