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"; import { addUserToEntity, getEntityWithRoles } from "@/utils/entities.be"; import { findBy } from "@/utils"; 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) return res.status(400).json({ error: "Invalid Code!" }); 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", entities: [], isVerified: !!codeDoc, }; await db.collection("users").insertOne(user); if (!!codeDoc) { await db.collection("codes").updateOne({ code: codeDoc.code }, { $set: { userId } }); if (codeDoc.entity) { const inviteEntity = await getEntityWithRoles(codeDoc.entity) if (inviteEntity) { const defaultRole = findBy(inviteEntity.roles, 'isDefault', true)! await addUserToEntity(userId, codeDoc.entity, defaultRole.id) } } } 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(), // apparently there's an issue with the verification email system // therefore we will skip this requirement for now isVerified: true, }; 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 }); }); }