mirror of
https://github.com/Discreetly/server.git
synced 2026-05-09 03:00:03 -04:00
818 lines
26 KiB
TypeScript
818 lines
26 KiB
TypeScript
import type { Express, RequestHandler, Request, Response } from 'express';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { serverConfig } from '../config/serverConfig';
|
|
import { genClaimCodeArray, pp } from '../utils';
|
|
import {
|
|
findRoomById,
|
|
findRoomsByIdentity,
|
|
findClaimCode,
|
|
updateClaimCode,
|
|
updateRoomIdentities,
|
|
findUpdatedRooms,
|
|
createRoom,
|
|
createSystemMessages,
|
|
removeRoom,
|
|
removeMessage
|
|
} from '../data/db/';
|
|
import { MessageI, RoomI } from 'discreetly-interfaces';
|
|
import { RLNFullProof } from 'rlnjs';
|
|
// import expressBasicAuth from 'express-basic-auth';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
function asyncHandler(fn: {
|
|
(req: Request, res: Response): Promise<void>;
|
|
(arg0: unknown, arg1: unknown): unknown;
|
|
}) {
|
|
return (req, res) => {
|
|
void Promise.resolve(fn(req, res)).catch((err) => {
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
throw new Error(err);
|
|
});
|
|
};
|
|
}
|
|
|
|
export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
|
// This code is used to fetch the server info from the api
|
|
// This is used to display the server info on the client side
|
|
app.get(['/', '/api'], (req, res) => {
|
|
pp('Express: fetching server info');
|
|
res.status(200).json(serverConfig);
|
|
});
|
|
|
|
// This code gets a room by its ID, and then checks if room is null.
|
|
// If room is null, it returns a 500 error.
|
|
// Otherwise, it returns a 200 status code and the room object.
|
|
|
|
app.get(['/room/:id', '/api/room/:id'], (req, res) => {
|
|
if (!req.params.id) {
|
|
res.status(400).json({ error: 'Bad Request' });
|
|
} else {
|
|
const requestRoomId = req.params.id ?? '0';
|
|
pp(String('Express: fetching room info for ' + req.params.id));
|
|
findRoomById(requestRoomId)
|
|
.then((room: RoomI) => {
|
|
if (!room) {
|
|
// This is set as a timeout to prevent someone from trying to brute force room ids
|
|
setTimeout(
|
|
() => res.status(500).json({ error: 'Internal Server Error' }),
|
|
1000
|
|
);
|
|
} else {
|
|
const {
|
|
roomId,
|
|
name,
|
|
rateLimit,
|
|
userMessageLimit,
|
|
membershipType,
|
|
identities,
|
|
bandadaAddress,
|
|
bandadaGroupId
|
|
} = room || {};
|
|
const id = String(roomId);
|
|
const roomResult: RoomI = {
|
|
id,
|
|
roomId,
|
|
name,
|
|
rateLimit,
|
|
userMessageLimit,
|
|
membershipType
|
|
};
|
|
// Add null check before accessing properties of room object
|
|
if (membershipType === 'BANDADA_GROUP') {
|
|
roomResult.bandadaAddress = bandadaAddress;
|
|
roomResult.bandadaGroupId = bandadaGroupId;
|
|
|
|
}
|
|
if (membershipType === 'IDENTITY_LIST') {
|
|
roomResult.identities = identities;
|
|
}
|
|
|
|
res.status(200).json(roomResult);
|
|
}
|
|
})
|
|
.catch((err) => console.error(err));
|
|
}
|
|
});
|
|
|
|
/** This function gets the rooms that a user is a member of.
|
|
* @param {string} idc - The id of the identity to get rooms for.
|
|
* @returns {Array} - An array of room objects.
|
|
*/
|
|
app.get(
|
|
['/rooms/:idc', '/api/rooms/:idc'],
|
|
asyncHandler(async (req: Request, res: Response) => {
|
|
try {
|
|
res.status(200).json(await findRoomsByIdentity(req.params.idc));
|
|
} catch (error) {
|
|
console.error(error);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
}
|
|
})
|
|
);
|
|
|
|
interface JoinData {
|
|
code: string;
|
|
idc: string;
|
|
}
|
|
|
|
/**
|
|
* This code is used to update the room identities of the rooms that the user is joining.
|
|
* The code updates the claim code and sets it to be claimed.
|
|
* It then updates the room identities of the user joining.
|
|
* Finally, it finds the rooms that have been updated and returns them.
|
|
* @param {string} code - The claim code to be updated
|
|
* @param {string} idc - The id of the identity to be added to the room
|
|
* @returns {Array} - An array of room objects
|
|
* @example {
|
|
* "code": "string",
|
|
* "idc": "string"
|
|
* }
|
|
*/
|
|
app.post(
|
|
['/join', '/api/join'],
|
|
asyncHandler(async (req: Request, res: Response) => {
|
|
const parsedBody: JoinData = req.body as JoinData;
|
|
|
|
if (!parsedBody.code || !parsedBody.idc) {
|
|
res
|
|
.status(400)
|
|
.json({ message: '{code: string, idc: string} expected' });
|
|
}
|
|
const { code, idc } = parsedBody;
|
|
console.debug('Invite Code:', code);
|
|
|
|
const foundCode = await findClaimCode(code);
|
|
if (foundCode && foundCode.expiresAt < Date.now()) {
|
|
await prisma.claimCodes.delete({
|
|
where: {
|
|
claimcode: code
|
|
}
|
|
});
|
|
res.status(400).json({ message: 'Claim Code Expired' });
|
|
return;
|
|
}
|
|
if (foundCode && (foundCode.usesLeft >= 0 || foundCode.usesLeft === -1)) {
|
|
const updatedCode = await updateClaimCode(code, idc);
|
|
if (updatedCode && updatedCode.usesLeft === 0) {
|
|
await prisma.claimCodes.delete({
|
|
where: {
|
|
claimcode: code
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
res.status(400).json({ message: 'Invalid Claim Code' });
|
|
return;
|
|
}
|
|
const roomIds = foundCode.roomIds;
|
|
console.log(roomIds);
|
|
const addedRooms = await updateRoomIdentities(idc, roomIds, foundCode.discordId!);
|
|
console.log(addedRooms);
|
|
const updatedRooms = await findUpdatedRooms(addedRooms as string[]);
|
|
|
|
// Return the room ids of the updated rooms
|
|
if (updatedRooms.length > 0) {
|
|
res.status(200).json({
|
|
status: 'valid',
|
|
roomIds: updatedRooms.map((room: RoomI) => room.roomId)
|
|
});
|
|
} else {
|
|
res.status(400).json({
|
|
message: `No rooms found or identity already exists in ${String(
|
|
roomIds
|
|
)}`
|
|
});
|
|
}
|
|
})
|
|
);
|
|
|
|
interface addRoomData {
|
|
roomName: string;
|
|
rateLimit: number;
|
|
userMessageLimit: number;
|
|
numClaimCodes?: number;
|
|
approxNumMockUsers?: number;
|
|
adminIdentities?: string[];
|
|
roomType?: string;
|
|
bandadaAddress?: string;
|
|
bandadaAPIKey?: string;
|
|
bandadaGroupId?: string;
|
|
membershipType?: string;
|
|
roomId?: string;
|
|
admin?: boolean;
|
|
discordIds?: string[];
|
|
}
|
|
|
|
/* ~~~~ ADMIN ENDPOINTS ~~~~ */
|
|
|
|
/** createRoom is used to create a new room in the database
|
|
* @param {string} roomName - The name of the room
|
|
* @param {number} rateLimit - The rate limit of the room
|
|
* @param {number} userMessageLimit - The user message limit of the room
|
|
* @param {number} numClaimCodes - The number of claim codes to generate
|
|
* @param {number} approxNumMockUsers - The approximate number of mock users to generate
|
|
* @param {string[]} adminIdentities - The identities of the admins of the room
|
|
* @param {string} type - The type of room
|
|
* @param {string} bandadaAddress - The address of the Bandada group
|
|
* @param {string} bandadaGroupId - The id of the Bandada group
|
|
* @param {string} bandadaAPIKey - The API key of the Bandada group
|
|
* @param {string} membershipType - The type of membership
|
|
* @param {string} roomId - The id of the room
|
|
* @param {string[]} discordIds - The ids of the discord users to add to the room
|
|
* @returns {void}
|
|
* @example {
|
|
* "roomName": "string",
|
|
* "rateLimit": number,
|
|
* "userMessageLimit": number,
|
|
* "numClaimCodes": number, // optional
|
|
* "approxNumMockUsers": number, // optional
|
|
* "adminIdentities": string[], // optional
|
|
* "roomType": "string", // optional
|
|
* "bandadaAddress": "string", // optional
|
|
* "bandadaGroupId": "string", // optional
|
|
* "bandadaAPIKey": "string", // optional
|
|
* "membershipType": "string" // optional if not an IDENTITY_LIST
|
|
* "roomId": "string", // optional
|
|
* "discordIds": string[] // optional
|
|
* }
|
|
*/
|
|
app.post(['/room/add', '/api/room/add'], adminAuth, (req, res) => {
|
|
const roomMetadata = req.body as addRoomData;
|
|
const roomName = roomMetadata.roomName;
|
|
const rateLimit = roomMetadata.rateLimit;
|
|
const userMessageLimit = roomMetadata.userMessageLimit;
|
|
const numClaimCodes = roomMetadata.numClaimCodes ?? 0;
|
|
const adminIdentities = roomMetadata.adminIdentities;
|
|
const approxNumMockUsers = roomMetadata.approxNumMockUsers;
|
|
const type = roomMetadata.roomType as unknown as string;
|
|
const bandadaAddress = roomMetadata.bandadaAddress;
|
|
const bandadaGroupId = roomMetadata.bandadaGroupId;
|
|
const bandadaAPIKey = roomMetadata.bandadaAPIKey;
|
|
const membershipType = roomMetadata.membershipType;
|
|
const roomId = roomMetadata.roomId;
|
|
createRoom(
|
|
roomName,
|
|
rateLimit,
|
|
userMessageLimit,
|
|
numClaimCodes,
|
|
approxNumMockUsers,
|
|
type,
|
|
adminIdentities,
|
|
bandadaAddress,
|
|
bandadaGroupId,
|
|
bandadaAPIKey,
|
|
membershipType,
|
|
roomId,
|
|
)
|
|
.then((result) => {
|
|
const response =
|
|
result === null
|
|
? { status: 400, message: 'Room already exists' }
|
|
: result
|
|
? {
|
|
status: 200,
|
|
message: 'Room created successfully',
|
|
roomId: result.roomId,
|
|
claimCodes: result.claimCodes
|
|
}
|
|
: { status: 500, error: 'Internal Server Error' };
|
|
|
|
res.status(response.status).json(response);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: String(err) });
|
|
});
|
|
});
|
|
|
|
/**
|
|
* This code is used to delete a room from the database.
|
|
* It takes in the roomId from the request body, and pass it to the removeRoom function.
|
|
* If removeRoom returns true, it means the room is deleted successfully, and the server returns a 200 status code.
|
|
* If removeRoom returns false, the server returns a 500 status code.
|
|
* If removeRoom throws an error, the server returns a 500 status code.
|
|
* @param {string} roomId - The id of the room to be deleted
|
|
* @returns {void}
|
|
* */
|
|
|
|
app.post(
|
|
['/room/:roomId/delete', '/api/room/:roomId/delete'],
|
|
adminAuth,
|
|
(req: Request, res: Response) => {
|
|
const { roomId } = req.body as { roomId: string };
|
|
removeRoom(roomId)
|
|
.then((result) => {
|
|
if (result) {
|
|
res.status(200).json({ message: 'Room deleted successfully' });
|
|
} else {
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: String(err) });
|
|
});
|
|
}
|
|
);
|
|
|
|
/**
|
|
* This code deletes a message from a room
|
|
* It takes in the roomId and messageId from the request body, and pass it to the removeMessage function.
|
|
* If removeMessage returns true, it means the message is deleted successfully, and the server returns a 200 status code.
|
|
* If removeMessage returns false, the server returns a 500 status code.
|
|
* If removeMessage throws an error, the server returns a 500 status code.
|
|
* @param {string} roomId - The id of the room to be deleted
|
|
* @param {string} messageId - The id of the message to be deleted
|
|
* @returns {void}
|
|
* */
|
|
|
|
app.post(
|
|
['/room/:roomId/message/delete', '/api/room/:roomId/message/delete'],
|
|
adminAuth,
|
|
(req, res) => {
|
|
const { roomId } = req.params;
|
|
const { messageId } = req.body as { messageId: string };
|
|
|
|
removeMessage(roomId, messageId)
|
|
.then((result) => {
|
|
if (result) {
|
|
res.status(200).json({ message: 'Message deleted successfully' });
|
|
} else {
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: String(err) });
|
|
});
|
|
}
|
|
);
|
|
|
|
/**
|
|
* This code handles the get request to get a list of messages for a particular room.
|
|
* It uses the Prisma client to query the database and return the messages for a particular room.
|
|
* It also parses the proof from a string to a JSON object.
|
|
* @param {string} id - The id of the room to get messages for
|
|
* @returns {void}
|
|
*/
|
|
app.get('/api/room/:id/messages', (req, res) => {
|
|
const { id } = req.params;
|
|
prisma.messages
|
|
.findMany({
|
|
take: 500,
|
|
orderBy: {
|
|
timeStamp: 'desc'
|
|
},
|
|
where: {
|
|
roomId: id
|
|
},
|
|
select: {
|
|
id: false,
|
|
message: true,
|
|
messageId: true,
|
|
proof: true,
|
|
roomId: true,
|
|
timeStamp: true
|
|
}
|
|
})
|
|
.then((messages) => {
|
|
messages.map((message: MessageI) => {
|
|
message.timeStamp = new Date(message.timeStamp as Date).getTime();
|
|
message.proof = JSON.parse(message.proof as string) as RLNFullProof;
|
|
message.epoch = message.proof.epoch;
|
|
});
|
|
pp('Express: fetching messages for room ' + id);
|
|
res.status(200).json(messages.reverse());
|
|
})
|
|
.catch((error: Error) => {
|
|
pp(error, 'error');
|
|
res.status(500).send('Error fetching messages');
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Endpoint to add claim codes to all rooms or a subset of rooms
|
|
* This code adds claim codes to the database.
|
|
* It is used by the admin panel to create claim codes.
|
|
* It takes in the number of codes to create, the rooms to add them to,
|
|
* and whether to add them to all rooms or just the selected ones.
|
|
* It generates the codes, then creates the ClaimCode objects in the database.
|
|
* The codes are added to the specified rooms, and are not claimed.
|
|
* @param {number} numCodes - The number of codes to add to the room
|
|
* @param {string[]} rooms - The ids of the rooms to add codes to
|
|
* @param {boolean} all - Whether to add codes to all rooms or just the selected ones
|
|
* @param {number} expiresAt - The date the codes expire - if not specified, defaults to 3 months from now
|
|
* @param {number} usesLeft - The number of uses left for the codes - if not specified, defaults to -1 (unlimited)
|
|
* @returns {void}
|
|
* @example {
|
|
* "numCodes": number,
|
|
* "rooms": string[],
|
|
* "all": boolean,
|
|
* "expiresAt": number, // optional
|
|
* "usesLeft": number // optional
|
|
* "discordId": string // optional
|
|
* }
|
|
*/
|
|
app.post(
|
|
['/addcode', '/api/addcode'],
|
|
adminAuth,
|
|
asyncHandler(async (req: Request, res: Response) => {
|
|
const { numCodes, rooms, all, expiresAt, usesLeft, discordId } = req.body as {
|
|
numCodes: number;
|
|
rooms: string[];
|
|
all: boolean;
|
|
expiresAt: number;
|
|
usesLeft: number;
|
|
discordId: string;
|
|
};
|
|
|
|
const currentDate = new Date();
|
|
const threeMonthsLater = new Date(currentDate).setMonth(
|
|
currentDate.getMonth() + 3
|
|
);
|
|
|
|
const codeExpires = expiresAt ? expiresAt : threeMonthsLater;
|
|
const query = all ? undefined : { where: { roomId: { in: rooms } } };
|
|
|
|
const codes = genClaimCodeArray(numCodes);
|
|
return await prisma.rooms.findMany(query).then((rooms) => {
|
|
const roomIds = rooms.map((room) => room.id);
|
|
const createCodes = codes.map((code) => {
|
|
return prisma.claimCodes
|
|
.create({
|
|
data: {
|
|
claimcode: code.claimcode,
|
|
roomIds: roomIds,
|
|
expiresAt: codeExpires,
|
|
usesLeft: usesLeft,
|
|
discordId: discordId
|
|
}
|
|
})
|
|
.then((newCode) => {
|
|
const updatePromises = rooms.map((room) => {
|
|
return prisma.rooms.update({
|
|
where: {
|
|
roomId: room.roomId
|
|
},
|
|
data: {
|
|
claimCodeIds: {
|
|
push: newCode.id
|
|
}
|
|
}
|
|
});
|
|
});
|
|
return Promise.all(updatePromises);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
});
|
|
|
|
return Promise.all(createCodes)
|
|
.then(() => {
|
|
res
|
|
.status(200)
|
|
.json({ message: 'Claim codes added successfully', codes });
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
});
|
|
})
|
|
);
|
|
|
|
/**
|
|
* Adds claim codes to a room
|
|
*
|
|
* @param {number} numCodes The number of codes to add to the room
|
|
* @param {number} expires The date the codes expire - if not specified, defaults to 3 months from now
|
|
* @param {number} usesLeft The number of uses left for the codes - if not specified, defaults to -1 (unlimited)
|
|
* @param {string} roomId The id of the room to add codes to
|
|
* @returns {void}
|
|
* @example {
|
|
* "numCodes": number
|
|
* }
|
|
*/
|
|
app.post(
|
|
['/room/:roomId/addcode', '/api/room/:roomId/addcode'],
|
|
adminAuth,
|
|
(req, res) => {
|
|
const { roomId } = req.params;
|
|
const { numCodes, expires, usesLeft } = req.body as {
|
|
numCodes: number;
|
|
expires: number;
|
|
usesLeft: number;
|
|
};
|
|
const codes = genClaimCodeArray(numCodes);
|
|
|
|
const currentDate = new Date();
|
|
const threeMonthsLater = new Date(currentDate).setMonth(
|
|
currentDate.getMonth() + 3
|
|
);
|
|
|
|
const codeExpires = expires ? expires : threeMonthsLater;
|
|
|
|
prisma.rooms
|
|
.findUnique({
|
|
where: { roomId: roomId },
|
|
include: { claimCodes: true }
|
|
})
|
|
.then((room) => {
|
|
if (!room) {
|
|
res.status(404).json({ error: 'Room not found' });
|
|
return;
|
|
}
|
|
// Map over the codes array and create a claim code for each code
|
|
const createCodes = codes.map((code) => {
|
|
return prisma.claimCodes.create({
|
|
data: {
|
|
claimcode: code.claimcode,
|
|
expiresAt: codeExpires,
|
|
usesLeft: usesLeft,
|
|
rooms: {
|
|
connect: {
|
|
roomId: roomId
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
return Promise.all(createCodes);
|
|
})
|
|
.then(() => {
|
|
res
|
|
.status(200)
|
|
.json({ message: 'Claim codes added successfully', codes });
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
}
|
|
);
|
|
|
|
// This fetches the claim/invite codes from the database and returns them as JSON
|
|
app.get(['/logclaimcodes', '/api/logclaimcodes'], adminAuth, (req, res) => {
|
|
pp('Express: fetching claim codes');
|
|
prisma.claimCodes
|
|
.findMany()
|
|
.then((claimCodes) => {
|
|
res.status(401).json(claimCodes);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
});
|
|
|
|
// GET all rooms from the database and return them as JSON
|
|
app.get(['/rooms', '/api/rooms'], adminAuth, (req, res) => {
|
|
pp(String('Express: fetching all rooms'));
|
|
prisma.rooms
|
|
.findMany()
|
|
.then((rooms) => {
|
|
res.status(200).json(rooms);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Sends system messages to the specified room, or all rooms if no room is specified
|
|
* @params {string} message - The message to send
|
|
* @params {string} roomId - The id of the room to send the message to
|
|
* @returns {void}
|
|
* @example {
|
|
* "message": "string",
|
|
* "roomId": "string" // optional
|
|
* }
|
|
*/
|
|
app.post(
|
|
'/admin/message',
|
|
adminAuth,
|
|
asyncHandler(async (req: Request, res: Response) => {
|
|
const { message, roomId } = req.body as {
|
|
message: string;
|
|
roomId?: string;
|
|
};
|
|
|
|
try {
|
|
// Function to send system messages
|
|
await createSystemMessages(message, roomId);
|
|
|
|
if (roomId) {
|
|
pp(`Express: sending system message: ${message} to ${roomId}`);
|
|
res.status(200).json({ message: `Message sent to room ${roomId}` });
|
|
} else {
|
|
pp(`Express: sending system message: ${message}`);
|
|
res.status(200).json({ message: 'Messages sent to all rooms' });
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
}
|
|
})
|
|
);
|
|
|
|
app.post(
|
|
'/room/:roomId/addAdmin',
|
|
adminAuth,
|
|
asyncHandler(async (req: Request, res: Response) => {
|
|
const { roomId } = req.params;
|
|
const { idc } = req.body as { idc: string };
|
|
try {
|
|
await prisma.rooms.update({
|
|
where: {
|
|
roomId: roomId
|
|
},
|
|
data: {
|
|
adminIdentities: {
|
|
push: idc
|
|
}
|
|
}
|
|
});
|
|
res.status(200).json({ message: `Admin added to room ${roomId}` });
|
|
} catch (err) {
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
}
|
|
})
|
|
);
|
|
|
|
/*---------------------DISCORD BOT APIS ---------------------*/
|
|
|
|
/**
|
|
* Creates a new guild in the database when the bot is added to a discord server.
|
|
* @param {string} guildId - The id of the guild to be added
|
|
* @returns {void}
|
|
*/
|
|
app.post('/api/discord/addguild', adminAuth, (req, res) => {
|
|
const { guildId } = req.body as {
|
|
guildId: string;
|
|
};
|
|
if (!guildId) {
|
|
res.status(400).json({ error: 'Bad Request' });
|
|
return;
|
|
}
|
|
prisma.discord
|
|
.upsert({
|
|
where: {
|
|
discordServerId: guildId
|
|
},
|
|
update: {},
|
|
create: {
|
|
discordServerId: guildId
|
|
}
|
|
})
|
|
.then(() => {
|
|
res.status(200).json({ message: 'Discord guild added successfully' });
|
|
return true;
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
return false;
|
|
});
|
|
});
|
|
/**
|
|
* This code creates a new role-room mapping in the database if one does not already exist,
|
|
* otherwise it updates the mapping with the new roles.
|
|
* @param {string[]} roles - The roles to be added to the room
|
|
* @param {string} roomId - The id of the room to be added
|
|
* @param {string} guildId - The id of the guild to be added
|
|
* @returns {void}
|
|
*/
|
|
|
|
app.post('/api/discord/addrole', adminAuth, (req, res) => {
|
|
const { roles, roomId, guildId } = req.body as {
|
|
roles: string[];
|
|
roomId: string;
|
|
guildId: string;
|
|
};
|
|
if (!roles || !roomId || !guildId) {
|
|
res.status(400).json({ error: 'Bad Request' });
|
|
return;
|
|
}
|
|
prisma.discordRoleRoomMapping
|
|
.upsert({
|
|
where: {
|
|
roomId: roomId
|
|
},
|
|
update: {
|
|
roles: {
|
|
set: roles
|
|
}
|
|
},
|
|
create: {
|
|
roomId: roomId,
|
|
discordServerId: guildId,
|
|
roles: {
|
|
set: roles
|
|
}
|
|
}
|
|
})
|
|
.then(() => {
|
|
res.status(200).json({ message: 'Discord roles added successfully' });
|
|
return true;
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
return false;
|
|
});
|
|
});
|
|
|
|
/**
|
|
* This code takes the roleId from the request body and tries to find all the rooms that have that role mapped to it.
|
|
* If it finds any, it returns them as a list in the response body.
|
|
* If it doesn't find any, it returns a 404 error.
|
|
* If it throws an error, it returns a 500 error.
|
|
* @param {string} roleId - The id of the role to be added
|
|
* @returns {string[]} - An array of room ids
|
|
* */
|
|
|
|
app.post('/api/discord/getrooms', adminAuth, asyncHandler(async (req: Request, res: Response) => {
|
|
const { roleId, discordId } = req.body as { roleId: string, discordId: string };
|
|
if (!roleId) {
|
|
res.status(400).json({ error: 'Bad Request' });
|
|
return;
|
|
}
|
|
const rooms = await prisma.gateWayIdentity.findFirst({
|
|
where: {
|
|
discordId: discordId
|
|
},
|
|
include: {
|
|
rooms: true
|
|
}
|
|
})
|
|
if (rooms) {
|
|
const discordRoleRoomMapping = await prisma.discordRoleRoomMapping.findMany({
|
|
where: {
|
|
roles: {
|
|
has: roleId
|
|
}
|
|
}
|
|
})
|
|
const roomIds = discordRoleRoomMapping.map((mapping) => mapping.roomId);
|
|
const filteredRooms = rooms.rooms.filter((room) => !roomIds.includes(room.roomId));
|
|
console.log(rooms);
|
|
res.status(200).json(filteredRooms);
|
|
}
|
|
// console.log(filteredRooms)
|
|
|
|
}));
|
|
|
|
/**
|
|
* This endpoint takes a discord user id and returns all rooms that the user is a part of.
|
|
* @param {string} discordUserId - The id of the discord user to get rooms for
|
|
* @returns {string[]} - An array of rooms that the user is a part of
|
|
*/
|
|
|
|
app.post('/api/discord/rooms', adminAuth, (req, res) => {
|
|
const { discordUserId } = req.body as { discordUserId: string };
|
|
prisma.gateWayIdentity
|
|
.findFirst({
|
|
where: {
|
|
discordId: discordUserId
|
|
},
|
|
include: {
|
|
rooms: true,
|
|
}
|
|
})
|
|
.then((identity) => {
|
|
return identity
|
|
}).catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
});
|
|
/**
|
|
* This endpoint gets all the rooms that a user is allowed to access based on their discordId.
|
|
* @params {string} discordId - The id of the discord user to get rooms for
|
|
* @returns {string[]} - An array of rooms that the user is a part of
|
|
*/
|
|
|
|
app.post('/api/discord/checkrooms', adminAuth, (req, res) => {
|
|
const { discordId } = req.body as { discordId: string };
|
|
prisma.discordRoleRoomMapping
|
|
.findMany({
|
|
where: {
|
|
discordServerId: discordId
|
|
}
|
|
})
|
|
.then((rooms) => {
|
|
res.status(200).json(rooms);
|
|
return rooms;
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
});
|
|
}
|