Finished refactoring

This commit is contained in:
Carlos Mesquita
2024-09-07 22:39:14 +01:00
parent c2b4bb29d6
commit 6e4ef249b8
16 changed files with 169 additions and 188 deletions

View File

@@ -1,7 +1,6 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next"; import type {NextApiRequest, NextApiResponse} from "next";
import {app, storage} from "@/firebase"; import {storage} from "@/firebase";
import {getFirestore, collection, getDocs, getDoc, doc, deleteDoc, setDoc} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import {Group} from "@/interfaces/user"; import {Group} from "@/interfaces/user";

View File

@@ -1,7 +1,5 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next"; import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase";
import {getFirestore, collection, getDocs, query, where} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import {Payment} from "@/interfaces/paypal"; import {Payment} from "@/interfaces/paypal";

View File

@@ -1,7 +1,7 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import {app, storage} from "@/firebase"; import { storage } from "@/firebase";
import {getFirestore, getDoc, doc, updateDoc, deleteField, setDoc} from "firebase/firestore"; import client from "@/lib/mongodb";
import { withIronSessionApiRoute } from "iron-session/next"; import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session"; import { sessionOptions } from "@/lib/session";
import { FilesStorage } from "@/interfaces/storage.files"; import { FilesStorage } from "@/interfaces/storage.files";
@@ -11,7 +11,7 @@ import fs from "fs";
import { ref, uploadBytes, deleteObject, getDownloadURL } from "firebase/storage"; import { ref, uploadBytes, deleteObject, getDownloadURL } from "firebase/storage";
import formidable from "formidable-serverless"; import formidable from "formidable-serverless";
const db = getFirestore(app); const db = client.db(process.env.MONGODB_DB);
const getPaymentField = (type: FilesStorage) => { const getPaymentField = (type: FilesStorage) => {
switch (type) { switch (type) {
@@ -25,16 +25,24 @@ const getPaymentField = (type: FilesStorage) => {
}; };
const handleDelete = async (paymentId: string, paymentField: "commissionTransfer" | "corporateTransfer") => { const handleDelete = async (paymentId: string, paymentField: "commissionTransfer" | "corporateTransfer") => {
const paymentRef = doc(db, "payments", paymentId); const paymentDoc = await db.collection("payments").findOne<Payment>({ id: paymentId })
const paymentDoc = await getDoc(paymentRef);
const {[paymentField]: paymentFieldPath} = paymentDoc.data() as Payment; if (paymentDoc) {
const { [paymentField]: paymentFieldPath } = paymentDoc;
// Create a reference to the file to delete // Create a reference to the file to delete
const documentRef = ref(storage, paymentFieldPath); const documentRef = ref(storage, paymentFieldPath);
await deleteObject(documentRef); await deleteObject(documentRef);
await updateDoc(paymentRef, { await db.collection("payments").deleteOne({ id: paymentId });
[paymentField]: deleteField(),
isPaid: false, await db.collection("payments").updateOne(
}); { id: paymentId },
{
$unset: { [paymentField]: "" },
$set: { isPaid: false }
}
);
}
}; };
const handleUpload = async (req: NextApiRequest, paymentId: string, paymentField: "commissionTransfer" | "corporateTransfer") => const handleUpload = async (req: NextApiRequest, paymentId: string, paymentField: "commissionTransfer" | "corporateTransfer") =>
@@ -54,11 +62,13 @@ const handleUpload = async (req: NextApiRequest, paymentId: string, paymentField
const snapshot = await uploadBytes(fileRef, binary); const snapshot = await uploadBytes(fileRef, binary);
fs.rmSync(file.path); fs.rmSync(file.path);
const paymentRef = doc(db, "payments", paymentId); await db.collection("payments").updateOne(
{ id: paymentId },
{
$set: { [paymentField]: snapshot.ref.fullPath }
}
);
await updateDoc(paymentRef, {
[paymentField]: snapshot.ref.fullPath,
});
resolve(snapshot.ref.fullPath); resolve(snapshot.ref.fullPath);
} catch (err) { } catch (err) {
reject(err); reject(err);
@@ -92,13 +102,16 @@ async function get(req: NextApiRequest, res: NextApiResponse) {
res.status(500).json({ error: "Failed to identify payment field" }); res.status(500).json({ error: "Failed to identify payment field" });
return; return;
} }
const paymentRef = doc(db, "payments", paymentId); const paymentRef = await db.collection("payments").findOne<Payment>({ id: paymentId })
const {[paymentField]: paymentFieldPath} = (await getDoc(paymentRef)).data() as Payment; if (paymentRef) {
const { [paymentField]: paymentFieldPath } = paymentRef;
// Create a reference to the file to delete // Create a reference to the file to delete
const documentRef = ref(storage, paymentFieldPath); const documentRef = ref(storage, paymentFieldPath);
const url = await getDownloadURL(documentRef); const url = await getDownloadURL(documentRef);
res.status(200).json({ url, name: documentRef.name }); res.status(200).json({ url, name: documentRef.name });
return;
}
} }
async function post(req: NextApiRequest, res: NextApiResponse) { async function post(req: NextApiRequest, res: NextApiResponse) {
@@ -116,11 +129,17 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
try { try {
const ref = await handleUpload(req, paymentId, paymentField); const ref = await handleUpload(req, paymentId, paymentField);
const updatedDoc = (await getDoc(doc(db, "payments", paymentId))).data() as Payment; const updatedDoc = await db.collection("payments").findOne<Payment>({ id: paymentId })
if (updatedDoc.commissionTransfer && updatedDoc.corporateTransfer) { if (updatedDoc && updatedDoc.commissionTransfer && updatedDoc.corporateTransfer) {
await setDoc(doc(db, "payments", paymentId), {isPaid: true}, {merge: true}); await db.collection("payments").updateOne(
{ id: paymentId },
{ $set: { isPaid: true } }
);
await setDoc(doc(db, "users", updatedDoc.corporate), {status: "active"}, {merge: true}); await db.collection("users").updateOne(
{ id: updatedDoc.corporate },
{ $set: { status: "active" } }
);
} }
res.status(200).json({ ref }); res.status(200).json({ ref });
} catch (error) { } catch (error) {

View File

@@ -1,7 +1,5 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next"; import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase";
import {getFirestore, collection, getDocs, setDoc, doc} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import {Group} from "@/interfaces/user"; import {Group} from "@/interfaces/user";

View File

@@ -1,7 +1,5 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next"; import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase";
import {getFirestore, getDocs, collection} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import client from "@/lib/mongodb"; import client from "@/lib/mongodb";

View File

@@ -1,7 +1,6 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next"; import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase"; import client from "@/lib/mongodb";
import {getFirestore, collection, getDocs, setDoc, doc} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import {Group} from "@/interfaces/user"; import {Group} from "@/interfaces/user";
@@ -11,7 +10,7 @@ import ShortUniqueId from "short-unique-id";
import axios from "axios"; import axios from "axios";
import {IntentionResult, PaymentIntention} from "@/interfaces/paymob"; import {IntentionResult, PaymentIntention} from "@/interfaces/paymob";
const db = getFirestore(app); const db = client.db(process.env.MONGODB_DB);
export default withIronSessionApiRoute(handler, sessionOptions); export default withIronSessionApiRoute(handler, sessionOptions);
@@ -26,14 +25,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
} }
async function get(req: NextApiRequest, res: NextApiResponse) { async function get(req: NextApiRequest, res: NextApiResponse) {
const snapshot = await getDocs(collection(db, "payments")); const snapshot = await db.collection("payments").find().toArray();
res.status(200).json(snapshot);
res.status(200).json(
snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})),
);
} }
async function post(req: NextApiRequest, res: NextApiResponse) { async function post(req: NextApiRequest, res: NextApiResponse) {

View File

@@ -1,7 +1,5 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next"; import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase";
import {getFirestore, collection, getDocs, setDoc, doc, getDoc, query, where} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import {Group, User} from "@/interfaces/user"; import {Group, User} from "@/interfaces/user";
@@ -11,8 +9,9 @@ import ShortUniqueId from "short-unique-id";
import axios from "axios"; import axios from "axios";
import {IntentionResult, PaymentIntention, TransactionResult} from "@/interfaces/paymob"; import {IntentionResult, PaymentIntention, TransactionResult} from "@/interfaces/paymob";
import moment from "moment"; import moment from "moment";
import client from "@/lib/mongodb";
const db = getFirestore(app); const db = client.db(process.env.MONGODB_DB);
export default async function handler(req: NextApiRequest, res: NextApiResponse) { export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") await post(req, res); if (req.method === "POST") await post(req, res);
@@ -32,11 +31,9 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
duration_unit: DurationUnit; duration_unit: DurationUnit;
}; };
const userSnapshot = await getDoc(doc(db, "users", userID as string)); const user = await db.collection("users").findOne<User>({ id: userID as string });
if (!userSnapshot.exists() || !duration || !duration_unit) return res.status(404).json({ok: false}); if (!user || !duration || !duration_unit) return res.status(404).json({ok: false});
const user = {...userSnapshot.data(), id: userSnapshot.id} as User;
const subscriptionExpirationDate = user.subscriptionExpirationDate; const subscriptionExpirationDate = user.subscriptionExpirationDate;
if (!subscriptionExpirationDate) return res.status(200).json({ok: false}); if (!subscriptionExpirationDate) return res.status(200).json({ok: false});
@@ -45,8 +42,13 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const updatedSubscriptionExpirationDate = moment(initialDate).add(duration, duration_unit).endOf("day").subtract(2, "hours").toISOString(); const updatedSubscriptionExpirationDate = moment(initialDate).add(duration, duration_unit).endOf("day").subtract(2, "hours").toISOString();
await setDoc(userSnapshot.ref, {subscriptionExpirationDate: updatedSubscriptionExpirationDate, status: "active"}, {merge: true}); await db.collection("users").updateOne(
await setDoc(doc(db, "paypalpayments", v4()), { { id: userID as string },
{ $set: {subscriptionExpirationDate: updatedSubscriptionExpirationDate, status: "active"} }
);
await db.collection("paypalpayments").insertOne({
id: v4(),
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
currency: transactionResult.transaction.currency, currency: transactionResult.transaction.currency,
orderId: transactionResult.transaction.id, orderId: transactionResult.transaction.id,
@@ -59,21 +61,19 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
}); });
if (user.type === "corporate") { if (user.type === "corporate") {
const groupsSnapshot = await getDocs(query(collection(db, "groups"), where("admin", "==", user.id))); const groups = await db.collection("groups").find<Group>({ admin: user.id }).toArray();
const groups = groupsSnapshot.docs.map((g) => ({...g.data(), id: g.id})) as Group[];
const participants = (await Promise.all( const participants = (await Promise.all(
groups.flatMap((x) => x.participants).map(async (x) => ({...(await getDoc(doc(db, "users", x))).data(), id: x})), groups.flatMap((x) => x.participants).map(async (x) => ({...(await db.collection("users").findOne({ id: x}))})),
)) as User[]; )) as User[];
const sameExpiryDateParticipants = participants.filter( const sameExpiryDateParticipants = participants.filter(
(x) => x.subscriptionExpirationDate === subscriptionExpirationDate && x.status !== "disabled", (x) => x.subscriptionExpirationDate === subscriptionExpirationDate && x.status !== "disabled",
); );
for (const participant of sameExpiryDateParticipants) { for (const participant of sameExpiryDateParticipants) {
await setDoc( await db.collection("users").updateOne(
doc(db, "users", participant.id), { id: participant.id },
{subscriptionExpirationDate: updatedSubscriptionExpirationDate, status: "active"}, { $set: {subscriptionExpirationDate: updatedSubscriptionExpirationDate, status: "active"} }
{merge: true},
); );
} }
} }

View File

@@ -1,7 +1,6 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next"; import type {NextApiRequest, NextApiResponse} from "next";
import {app} from "@/firebase"; import client from "@/lib/mongodb";
import {getFirestore, setDoc, doc, getDocs, query, collection, where} from "firebase/firestore";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import {Type, User} from "@/interfaces/user"; import {Type, User} from "@/interfaces/user";
@@ -12,7 +11,8 @@ import * as Stripe from "stripe";
import ShortUniqueId from "short-unique-id"; import ShortUniqueId from "short-unique-id";
import moment from "moment"; import moment from "moment";
const db = getFirestore(app);
const db = client.db(process.env.MONGODB_DB);
export default async function handler(req: NextApiRequest, res: NextApiResponse) { export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const {email, days, key, checkout} = req.body as {email: string; days: string; key: string; checkout: string}; const {email, days, key, checkout} = req.body as {email: string; days: string; key: string; checkout: string};
@@ -24,41 +24,44 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const uid = new ShortUniqueId(); const uid = new ShortUniqueId();
const code = uid.randomUUID(6); const code = uid.randomUUID(6);
const codeCheckerRef = await getDocs(query(collection(db, "codes"), where("checkout", "==", checkout))); const codeCheckerRef = await db.collection("codes").find({ checkout: checkout }).toArray();
if (codeCheckerRef.docs.length !== 0) { if (codeCheckerRef.length !== 0) {
res.status(401).json({ok: false}); res.status(401).json({ok: false});
return; return;
} }
const emailCheckerRef = await getDocs(query(collection(db, "users"), where("email", "==", email))); const emailCheckerRef = await db.collection("users").find({ email: email }).toArray();
if (emailCheckerRef.docs.length !== 0) { if (emailCheckerRef.length !== 0) {
const user = emailCheckerRef.docs[0]; const user = emailCheckerRef[0];
if (!user.data().subscriptionExpirationDate) { if (!user.subscriptionExpirationDate) {
res.status(200).json({ok: true}); res.status(200).json({ok: true});
return; return;
} }
const codeUserRef = await getDocs(query(collection(db, "codes"), where("userId", "==", user.id))); const codeUserRef = await db.collection("codes").find({ userId: user.id }).toArray();
const userCode = codeUserRef.docs[0]; const userCode = codeUserRef[0];
if (userCode.data().checkout && userCode.data().checkout === checkout) { if (userCode.checkout && userCode.checkout === checkout) {
res.status(401).json({ok: false}); res.status(401).json({ok: false});
return; return;
} }
await db.collection("users").updateOne(
await setDoc( { id: user.id },
user.ref, { $set: {subscriptionExpirationDate: moment(user.subscriptionExpirationDate).add(days, "days").toISOString()} }
{subscriptionExpirationDate: moment(user.data().subscriptionExpirationDate).add(days, "days").toISOString()}, );
{merge: true}, await db.collection("codes").updateOne(
{ id: userCode.id },
{ $set: {checkout} }
); );
await setDoc(userCode.ref, {checkout}, {merge: true});
res.status(200).json({ok: true}); res.status(200).json({ok: true});
return; return;
} }
const codeRef = doc(db, "codes", code); await db.collection("codes").updateOne(
await setDoc(codeRef, {type: "student", code, expiryDate: moment(new Date()).add(days, "days").toISOString(), checkout}); { id: code },
{ $set: {type: "student", code, expiryDate: moment(new Date()).add(days, "days").toISOString(), checkout} }
);
const transport = prepareMailer(); const transport = prepareMailer();
const mailOptions = prepareMailOptions( const mailOptions = prepareMailOptions(

View File

@@ -2,7 +2,6 @@ import {PERMISSIONS} from "@/constants/userPermissions";
import {app, adminApp} from "@/firebase"; import {app, adminApp} from "@/firebase";
import {Group, User} from "@/interfaces/user"; import {Group, User} from "@/interfaces/user";
import {sessionOptions} from "@/lib/session"; 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 {getAuth} from "firebase-admin/auth";
import {withIronSessionApiRoute} from "iron-session/next"; import {withIronSessionApiRoute} from "iron-session/next";
import {NextApiRequest, NextApiResponse} from "next"; import {NextApiRequest, NextApiResponse} from "next";

View File

@@ -1,7 +1,6 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import { app, storage } from "@/firebase"; import { app, storage } from "@/firebase";
import { getFirestore, collection, getDocs, getDoc, doc, setDoc, query, where } from "firebase/firestore";
import { withIronSessionApiRoute } from "iron-session/next"; import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session"; import { sessionOptions } from "@/lib/session";
import { Group, User } from "@/interfaces/user"; import { Group, User } from "@/interfaces/user";

View File

@@ -1,35 +1,28 @@
import {app} from "@/firebase"; import client from "@/lib/mongodb";
import { Assignment } from "@/interfaces/results"; import { Assignment } from "@/interfaces/results";
import {collection, getDocs, getFirestore, query, where} from "firebase/firestore";
import { getAllAssignersByCorporate } from "@/utils/groups.be"; import { getAllAssignersByCorporate } from "@/utils/groups.be";
const db = getFirestore(app); const db = client.db(process.env.MONGODB_DB);
export const getAssignmentsByAssigner = async (id: string, startDate?: Date, endDate?: Date) => { export const getAssignmentsByAssigner = async (id: string, startDate?: Date, endDate?: Date) => {
const {docs} = await getDocs( let query: any = { assigner: id };
query(
collection(db, "assignments"), if (startDate) {
...[ query.startDate = { $gte: startDate.toISOString() };
where("assigner", "==", id),
...(startDate ? [where("startDate", ">=", startDate.toISOString())] : []),
// firebase doesnt accept compound queries so we have to filter on the server
// ...endDate ? [where("endDate", "<=", endDate)] : [],
],
),
);
if (endDate) {
return docs.map((x) => ({...(x.data() as Assignment), id: x.id})).filter((x) => new Date(x.endDate) <= endDate) as Assignment[];
} }
return docs.map((x) => ({...x.data(), id: x.id})) as Assignment[];
if (endDate) {
query.endDate = { $lte: endDate.toISOString() };
}
return await db.collection("assignments").find<Assignment>(query).toArray();
}; };
export const getAssignments = async () => { export const getAssignments = async () => {
const {docs} = await getDocs(collection(db, "assignments")); return await db.collection("assignments").find<Assignment>({}).toArray();
return docs.map((x) => ({...x.data(), id: x.id})) as Assignment[];
}; };
export const getAssignmentsByAssignerBetweenDates = async (id: string, startDate: Date, endDate: Date) => { export const getAssignmentsByAssignerBetweenDates = async (id: string, startDate: Date, endDate: Date) => {
const {docs} = await getDocs(query(collection(db, "assignments"), where("assigner", "==", id))); return await db.collection("assignments").find<Assignment>({assigner: id}).toArray();
return docs.map((x) => ({...x.data(), id: x.id})) as Assignment[];
}; };
export const getAssignmentsByAssigners = async (ids: string[], startDate?: Date, endDate?: Date) => { export const getAssignmentsByAssigners = async (ids: string[], startDate?: Date, endDate?: Date) => {

View File

@@ -1,10 +1,8 @@
import {app} from "@/firebase"; import client from "@/lib/mongodb";
import {Code} from "@/interfaces/user"; import {Code} from "@/interfaces/user";
import {collection, getDocs, getFirestore, query, where} from "firebase/firestore";
const db = getFirestore(app); const db = client.db(process.env.MONGODB_DB);
export const getUserCodes = async (id: string): Promise<Code[]> => { export const getUserCodes = async (id: string): Promise<Code[]> => {
const codeDocs = await getDocs(query(collection(db, "codes"), where("creator", "==", id))); return await db.collection("codes").find<Code>({creator: id}).toArray();
return codeDocs.docs.map((x) => ({...(x.data() as Code), id})) as Code[];
}; };

View File

@@ -1,5 +1,3 @@
import {app} from "@/firebase";
import {getFirestore, doc, getDoc} from "firebase/firestore";
import {CEFR_STEPS} from "@/resources/grading"; import {CEFR_STEPS} from "@/resources/grading";
import {getUserCorporate} from "@/utils/groups.be"; import {getUserCorporate} from "@/utils/groups.be";
import {User} from "@/interfaces/user"; import {User} from "@/interfaces/user";

View File

@@ -1,7 +1,6 @@
import {app} from "@/firebase"; import {app} from "@/firebase";
import {CorporateUser, Group, MasterCorporateUser, StudentUser, TeacherUser, User} from "@/interfaces/user"; import {CorporateUser, Group, MasterCorporateUser, StudentUser, TeacherUser, User} from "@/interfaces/user";
import client from "@/lib/mongodb"; import client from "@/lib/mongodb";
import {collection, doc, getDoc, getDocs, getFirestore, query, setDoc, where} from "firebase/firestore";
import moment from "moment"; import moment from "moment";
import {getUser} from "./users.be"; import {getUser} from "./users.be";
import {getSpecificUsers} from "./users.be"; import {getSpecificUsers} from "./users.be";

View File

@@ -1,20 +1,19 @@
import {app, adminApp} from "@/firebase"; import client from "@/lib/mongodb";
import {getAuth} from "firebase-admin/auth";
import {collection, deleteDoc, doc, getDoc, getDocs, getFirestore, query, setDoc, where} from "firebase/firestore";
import {Permission, PermissionType, permissions, PermissionTopic} from "@/interfaces/permissions"; import {Permission, PermissionType, permissions, PermissionTopic} from "@/interfaces/permissions";
import {v4} from "uuid"; import {v4} from "uuid";
const db = getFirestore(app); const db = client.db(process.env.MONGODB_DB);
async function createPermission(topic: string, type: string) { async function createPermission(topic: string, type: string) {
const permData = doc(db, "permissions", v4()); /*const permData = doc(db, "permissions", v4());
const permDoc = await getDoc(permData); const permDoc = await getDoc(permData);
if (permDoc.exists()) { if (permDoc.exists()) {
return true; return true;
} }*/
await setDoc(permData, { await db.collection("permissions").insertOne({
id: v4(),
type, type,
topic, topic,
users: [], users: [],
@@ -48,7 +47,7 @@ export async function getUserPermissions(id: string) {
} }
export async function bootstrap() { export async function bootstrap() {
await permissions permissions
.reduce((accm: PermissionsHelperList[], permissionData) => { .reduce((accm: PermissionsHelperList[], permissionData) => {
return [ return [
...accm, ...accm,
@@ -64,26 +63,18 @@ export async function bootstrap() {
} }
export async function getPermissionDoc(id: string) { export async function getPermissionDoc(id: string) {
const docRef = doc(db, "permissions", id); const perm = await db.collection("permissions").findOne<Permission>({ id: id });
const docSnap = await getDoc(docRef);
if (docSnap.exists()) { if (perm) {
return docSnap.data() as Permission; return perm;
} }
throw new Error("Permission not found"); throw new Error("Permission not found");
} }
export async function getPermissionDocs() { export async function getPermissionDocs() {
const q = query(collection(db, "permissions")); // TODO: Don't know if this was finished
// firebase is missing something like array-not-contains // firebase is missing something like array-not-contains
const snapshot = await getDocs(q); return await db.collection("permissions").find<Permission>({}).toArray();
const docs = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
})) as Permission[];
return docs;
} }

View File

@@ -1,32 +1,29 @@
// updating specific user changes other users // updating specific user changes other users
// for example, updating the status of a corporate user should update the status of all users in the same corporate group // for example, updating the status of a corporate user should update the status of all users in the same corporate group
import { UserStatus, User } from "../interfaces/user"; import { UserStatus, User } from "../interfaces/user";
import {getFirestore, collection, getDocs, getDoc, doc, setDoc, query, where} from "firebase/firestore"; import client from "@/lib/mongodb";
import {app} from "@/firebase";
const db = getFirestore(app); const db = client.db(process.env.MONGODB_DB);
export const propagateStatusChange = (userId: string, status: UserStatus) => export const propagateStatusChange = (userId: string, status: UserStatus) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
getDoc(doc(db, "users", userId)) db.collection("users").findOne<User>({ id: userId })
.then((docUser) => { .then((docUser) => {
const user = docUser.data() as User; if (!docUser) return;
const user = docUser;
// only update the status of the user's groups if the user is a corporate user // only update the status of the user's groups if the user is a corporate user
if (user.type === "corporate" || user.type === "mastercorporate") { if (user.type === "corporate" || user.type === "mastercorporate") {
getDocs(query(collection(db, "groups"), where("admin", "==", userId))).then(async (userGroupsRef) => { db.collection("groups").find({ admin: userId }).toArray().then(async (userGroupsRef) => {
const userGroups = userGroupsRef.docs.map((x) => x.data()); const userGroups = userGroupsRef.map((x) => x.data());
const targetUsers = [...new Set(userGroups.flatMap((g) => g.participants).filter((u) => u))]; const targetUsers = [...new Set(userGroups.flatMap((g) => g.participants).filter((u) => u))];
Promise.all( Promise.all(
targetUsers.map(async (targetUserId) => { targetUsers.map(async (targetUserId) => {
const ref = await getDoc(doc(db, "users", targetUserId)); const ref = await db.collection("users").findOne<User>({ id: targetUserId });
if (!ref) return null;
if (!ref.exists()) return null; return ref;
const data = ref.data() as User;
return {...data, id: targetUserId};
}), }),
) )
.then((data) => { .then((data) => {
@@ -40,7 +37,7 @@ export const propagateStatusChange = (userId: string, status: UserStatus) =>
return; return;
} }
Promise.all(filtered.map((user: User) => setDoc(doc(db, "users", user.id), {status}, {merge: true}))) Promise.all(filtered.map((user: User) => db.collection("users").updateOne({ id: user.id }, { $set: { status } })))
.then(() => { .then(() => {
resolve(true); resolve(true);
}) })
@@ -69,25 +66,21 @@ export const propagateStatusChange = (userId: string, status: UserStatus) =>
export const propagateExpiryDateChanges = (userId: string, initialExpiryDate: Date | null | undefined, subscriptionExpirationDate: Date | null) => export const propagateExpiryDateChanges = (userId: string, initialExpiryDate: Date | null | undefined, subscriptionExpirationDate: Date | null) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
getDoc(doc(db, "users", userId)) db.collection("users").findOne<User>({ id: userId })
.then((docUser) => { .then((user) => {
const user = docUser.data() as User; if (!user) return;
// only update the status of the user's groups if the user is a corporate user // only update the status of the user's groups if the user is a corporate user
if (user.type === "corporate") { if (user.type === "corporate") {
getDocs(query(collection(db, "groups"), where("admin", "==", userId))).then(async (userGroupsRef) => { db.collection("groups").find({ admin: userId }).toArray().then(async (userGroupsRef) => {
const userGroups = userGroupsRef.docs.map((x) => x.data()); const userGroups = userGroupsRef.map((x) => x.data());
const targetUsers = [...new Set(userGroups.flatMap((g) => g.participants).filter((u) => u))]; const targetUsers = [...new Set(userGroups.flatMap((g) => g.participants).filter((u) => u))];
Promise.all( Promise.all(
targetUsers.map(async (targetUserId) => { targetUsers.map(async (targetUserId) => {
const ref = await getDoc(doc(db, "users", targetUserId)); const ref = await db.collection("users").findOne<User>({ id: targetUserId });
return ref;
if (!ref.exists()) return null;
const data = ref.data() as User;
return {...data, id: ref.id};
}), }),
) )
.then(async (data) => { .then(async (data) => {
@@ -101,7 +94,10 @@ export const propagateExpiryDateChanges = (userId: string, initialExpiryDate: Da
if (filtered.length === 0) return; if (filtered.length === 0) return;
for (const user of filtered) { for (const user of filtered) {
await setDoc(doc(db, "users", user.id), {subscriptionExpirationDate}, {merge: true}); await db.collection("users").updateOne(
{ id: user.id },
{ $set: { subscriptionExpirationDate } }
);
} }
resolve(true); resolve(true);