158 lines
4.3 KiB
TypeScript
158 lines
4.3 KiB
TypeScript
|
|
import { sessionOptions } from '@/lib/session';
|
|
import { withIronSessionApiRoute } from 'iron-session/next';
|
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
import client from "@/lib/mongodb";
|
|
|
|
const db = client.db(process.env.MONGODB_DB);
|
|
|
|
export default withIronSessionApiRoute(handler, sessionOptions);
|
|
|
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
const { op } = req.query
|
|
|
|
if (req.method === 'GET') {
|
|
switch (op) {
|
|
default:
|
|
res.status(400).json({ error: 'Invalid operation!' })
|
|
}
|
|
}
|
|
else if (req.method === 'POST') {
|
|
switch (op) {
|
|
case 'existantGroupIds':
|
|
res.status(200).json(await existantGroupIds(req.body.names));
|
|
break;
|
|
case 'crossRefOwnership':
|
|
res.status(200).json(await crossRefOwnership(req.body));
|
|
break;
|
|
case 'getIds':
|
|
res.status(200).json(await getIds(req.body));
|
|
break;
|
|
case 'deletePriorEntitiesGroups':
|
|
await deletePriorEntitiesGroups(req.body);
|
|
res.status(200).json({ ok: true });
|
|
break;
|
|
default:
|
|
res.status(400).json({ error: 'Invalid operation!' })
|
|
}
|
|
} else {
|
|
res.status(400).end(`Method ${req.method} Not Allowed`)
|
|
}
|
|
}
|
|
|
|
async function crossRefOwnership(body: any): Promise<string[]> {
|
|
const { userId, classrooms, entity } = body;
|
|
|
|
const existingClassrooms = await db.collection('groups')
|
|
.find({
|
|
name: { $in: classrooms },
|
|
admin: { $ne: userId }
|
|
})
|
|
.project({ name: 1, admin: 1, _id: 0 })
|
|
.toArray();
|
|
|
|
if (existingClassrooms.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
const adminUsers = await db.collection('users')
|
|
.find({
|
|
id: { $in: existingClassrooms.map(classroom => classroom.admin) }
|
|
})
|
|
.project({ id: 1, entities: 1, _id: 0 })
|
|
.toArray();
|
|
|
|
const adminEntitiesMap = new Map(
|
|
adminUsers.map(admin => [
|
|
admin.id,
|
|
admin.entities?.map((e: any) => e.id) || []
|
|
])
|
|
);
|
|
|
|
return Array.from(new Set(
|
|
existingClassrooms
|
|
.filter(classroom => {
|
|
const adminEntities = adminEntitiesMap.get(classroom.admin) || [];
|
|
return adminEntities.includes(entity);
|
|
})
|
|
.map(classroom => classroom.name)
|
|
));
|
|
}
|
|
|
|
async function getIds(body: any): Promise<Record<string, string>> {
|
|
const { names, userEmails } = body;
|
|
|
|
const existingGroups: any[] = await db.collection('groups')
|
|
.find({ name: { $in: names } })
|
|
.project({ name: 1, id: 1, _id: 0 })
|
|
.toArray();
|
|
|
|
const users: any[] = await db.collection('users')
|
|
.find({ email: { $in: userEmails } })
|
|
.project({ email: 1, id: 1, _id: 0 })
|
|
.toArray();
|
|
|
|
return {
|
|
groups: existingGroups.reduce((acc, group) => {
|
|
acc[group.name] = group.id;
|
|
return acc;
|
|
}, {} as Record<string, string>),
|
|
users: users.reduce((acc, user) => {
|
|
acc[user.email] = user.id;
|
|
return acc;
|
|
}, {} as Record<string, string>)
|
|
};
|
|
}
|
|
|
|
|
|
async function deletePriorEntitiesGroups(body: any) {
|
|
const { ids, entity } = body;
|
|
if (!Array.isArray(ids) || ids.length === 0 || !entity) {
|
|
return;
|
|
}
|
|
|
|
const users = await db.collection('users')
|
|
.find({ id: { $in: ids } })
|
|
.project({ id: 1, entities: 1, _id: 0 })
|
|
.toArray();
|
|
|
|
// if the user doesn't have the target entity mark them for all groups deletion
|
|
const toDeleteUserIds = users
|
|
.filter(user => !user.entities?.some((e: any) => e.id === entity))
|
|
.map(user => user.id);
|
|
|
|
if (toDeleteUserIds.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const affectedGroups = await db.collection('groups')
|
|
.find({ participants: { $in: toDeleteUserIds } })
|
|
.project({ id: 1, _id: 0 })
|
|
.toArray();
|
|
|
|
await db.collection('groups').updateMany(
|
|
{ participants: { $in: toDeleteUserIds } },
|
|
{ $pull: { participants: { $in: toDeleteUserIds } } } as any
|
|
);
|
|
|
|
// delete groups that were updated and have no participants
|
|
await db.collection('groups').deleteMany({
|
|
id: { $in: affectedGroups.map(g => g.id) },
|
|
participants: { $size: 0 }
|
|
});
|
|
}
|
|
|
|
async function existantGroupIds(names: string[]) {
|
|
const existingGroups = await db.collection('groups')
|
|
.find({
|
|
name: { $in: names }
|
|
})
|
|
.project({ id: 1, name: 1, _id: 0 })
|
|
.toArray();
|
|
|
|
return existingGroups.reduce((acc, group) => {
|
|
acc[group.name] = group.id;
|
|
return acc;
|
|
}, {} as Record<string, string>);
|
|
}
|