mirror of
https://github.com/Discreetly/server.git
synced 2026-01-10 13:08:07 -05:00
feature(express) endpoint for sending system messages to all rooms
feature(jest) tests for system messages endpoint
This commit is contained in:
@@ -107,6 +107,25 @@ export function findUpdatedRooms(roomIds: string[]): Promise<RoomI[]> {
|
||||
});
|
||||
}
|
||||
|
||||
export function createSystemMessages(message: string): Promise<any> {
|
||||
return prisma.rooms.findMany()
|
||||
.then(rooms => {
|
||||
const createMessages = rooms.map(room => {
|
||||
return prisma.messages.create({
|
||||
data: {
|
||||
message,
|
||||
roomId: room.roomId,
|
||||
messageId: "0",
|
||||
proof: JSON.stringify({}),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(createMessages);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new room with the given name and optional parameters.
|
||||
* @param {string} name - The name of the room.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Express, RequestHandler, Request, Response } from 'express';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { serverConfig } from '../config/serverConfig';
|
||||
import { pp } from '../utils';
|
||||
import type { Express, RequestHandler, Request, Response } from "express";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { serverConfig } from "../config/serverConfig";
|
||||
import { pp } from "../utils";
|
||||
import {
|
||||
getRoomByID,
|
||||
getRoomsByIdentity,
|
||||
@@ -9,9 +9,10 @@ import {
|
||||
updateClaimCode,
|
||||
updateRoomIdentities,
|
||||
findUpdatedRooms,
|
||||
createRoom
|
||||
} from '../data/db';
|
||||
import { RoomI } from 'discreetly-interfaces';
|
||||
createRoom,
|
||||
createSystemMessages,
|
||||
} from "../data/db";
|
||||
import { RoomI } from "discreetly-interfaces";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -28,22 +29,25 @@ function asyncHandler(fn: {
|
||||
}
|
||||
|
||||
export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
app.get(['/', '/api'], (req, res) => {
|
||||
pp('Express: fetching server info');
|
||||
app.get(["/", "/api"], (req, res) => {
|
||||
pp("Express: fetching server info");
|
||||
res.status(200).json(serverConfig);
|
||||
});
|
||||
|
||||
app.get(['/room/:id', '/api/room/:id'], (req, res) => {
|
||||
app.get(["/room/:id", "/api/room/:id"], (req, res) => {
|
||||
if (!req.params.id) {
|
||||
res.status(400).json({ error: 'Bad Request' });
|
||||
res.status(400).json({ error: "Bad Request" });
|
||||
} else {
|
||||
const requestRoomId = req.params.id ?? '0';
|
||||
pp(String('Express: fetching room info for ' + req.params.id));
|
||||
const requestRoomId = req.params.id ?? "0";
|
||||
pp(String("Express: fetching room info for " + req.params.id));
|
||||
getRoomByID(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);
|
||||
setTimeout(
|
||||
() => res.status(500).json({ error: "Internal Server Error" }),
|
||||
1000
|
||||
);
|
||||
} else {
|
||||
// Add null check before accessing properties of room object
|
||||
const { roomId, name, rateLimit, userMessageLimit } = room || {};
|
||||
@@ -54,8 +58,10 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
}
|
||||
});
|
||||
|
||||
app.get(['/rooms/:idc', '/api/rooms/:idc'], async (req, res) => {
|
||||
pp(String('Express: fetching rooms by identityCommitment ' + req.params.idc));
|
||||
app.get(["/rooms/:idc", "/api/rooms/:idc"], async (req, res) => {
|
||||
pp(
|
||||
String("Express: fetching rooms by identityCommitment " + req.params.idc)
|
||||
);
|
||||
res.status(200).json(await getRoomsByIdentity(req.params.idc));
|
||||
});
|
||||
|
||||
@@ -65,20 +71,22 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
}
|
||||
|
||||
app.post(
|
||||
['/join', '/api/join'],
|
||||
["/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' });
|
||||
res
|
||||
.status(400)
|
||||
.json({ message: "{code: string, idc: string} expected" });
|
||||
}
|
||||
const { code, idc } = parsedBody;
|
||||
console.log('Invite Code:', code);
|
||||
console.log("Invite Code:", code);
|
||||
|
||||
// Check if claim code is valid and not used before
|
||||
const codeStatus = await findClaimCode(code);
|
||||
if (!codeStatus || codeStatus.claimed) {
|
||||
res.status(400).json({ message: 'Claim code already used' });
|
||||
res.status(400).json({ message: "Claim code already used" });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -94,8 +102,8 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
|
||||
// Return the room ids of the updated rooms
|
||||
res.status(200).json({
|
||||
status: 'valid',
|
||||
roomIds: updatedRooms.map((room: RoomI) => room.roomId)
|
||||
status: "valid",
|
||||
roomIds: updatedRooms.map((room: RoomI) => room.roomId),
|
||||
});
|
||||
})
|
||||
);
|
||||
@@ -108,8 +116,8 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
}
|
||||
|
||||
/* ~~~~ ADMIN ENDPOINTS ~~~~ */
|
||||
app.post(['/room/add', '/api/room/add'], adminAuth, (req, res) => {
|
||||
console.log(req.body)
|
||||
app.post(["/room/add", "/api/room/add"], adminAuth, (req, res) => {
|
||||
console.log(req.body);
|
||||
const roomMetadata = req.body as addRoomData;
|
||||
console.log(roomMetadata);
|
||||
const roomName = roomMetadata.roomName;
|
||||
@@ -121,9 +129,9 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
console.log(result);
|
||||
if (result) {
|
||||
// TODO should return roomID and claim codes if they are generated
|
||||
res.status(200).json({ message: 'Room created successfully' });
|
||||
res.status(200).json({ message: "Room created successfully" });
|
||||
} else {
|
||||
res.status(500).json({ error: 'Internal Server Error' });
|
||||
res.status(500).json({ error: "Internal Server Error" });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -132,26 +140,26 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/room/:id/messages', (req, res) => {
|
||||
app.get("/api/room/:id/messages", (req, res) => {
|
||||
const { id } = req.params;
|
||||
prisma.messages
|
||||
.findMany({
|
||||
where: {
|
||||
roomId: id
|
||||
}
|
||||
roomId: id,
|
||||
},
|
||||
})
|
||||
.then((messages) => {
|
||||
pp('Express: fetching messages for room ' + id);
|
||||
pp("Express: fetching messages for room " + id);
|
||||
res.status(200).json(messages);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
pp(error, 'error');
|
||||
res.status(500).send('Error fetching messages');
|
||||
pp(error, "error");
|
||||
res.status(500).send("Error fetching messages");
|
||||
});
|
||||
});
|
||||
|
||||
app.get(['/logclaimcodes', '/api/logclaimcodes'], adminAuth, (req, res) => {
|
||||
pp('Express: fetching claim codes');
|
||||
app.get(["/logclaimcodes", "/api/logclaimcodes"], adminAuth, (req, res) => {
|
||||
pp("Express: fetching claim codes");
|
||||
prisma.claimCodes
|
||||
.findMany()
|
||||
.then((claimCodes) => {
|
||||
@@ -159,12 +167,12 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Internal Server Error' });
|
||||
res.status(500).json({ error: "Internal Server Error" });
|
||||
});
|
||||
});
|
||||
|
||||
app.get(['/rooms', '/api/rooms'], adminAuth, (req, res) => {
|
||||
pp(String('Express: fetching all rooms'));
|
||||
app.get(["/rooms", "/api/rooms"], adminAuth, (req, res) => {
|
||||
pp(String("Express: fetching all rooms"));
|
||||
prisma.rooms
|
||||
.findMany()
|
||||
.then((rooms) => {
|
||||
@@ -172,7 +180,19 @@ export function initEndpoints(app: Express, adminAuth: RequestHandler) {
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Internal Server Error' });
|
||||
res.status(500).json({ error: "Internal Server Error" });
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/admin/message", adminAuth, async (req, res) => {
|
||||
const { message } = req.body;
|
||||
pp(String("Express: sending system message: " + message));
|
||||
try {
|
||||
await createSystemMessages(message);
|
||||
res.status(200).json({ message: "Messages sent to all rooms" });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: "Internal Server Error" });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
const request = require("supertest");
|
||||
import _app from "../src/server";
|
||||
import { genId } from "discreetly-interfaces";
|
||||
@@ -13,11 +12,11 @@ process.env.PORT = "3001";
|
||||
|
||||
beforeAll(async () => {
|
||||
const prismaTest = new PrismaClient();
|
||||
await prismaTest.messages.deleteMany();
|
||||
await prismaTest.rooms.deleteMany();
|
||||
await prismaTest.claimCodes.deleteMany();
|
||||
});
|
||||
|
||||
|
||||
const room = {
|
||||
roomName: randomRoomName(),
|
||||
rateLimit: 1000,
|
||||
@@ -27,12 +26,12 @@ const room = {
|
||||
|
||||
const roomByIdTest = genId(serverConfig.id, room.roomName).toString();
|
||||
|
||||
|
||||
let testCode = "";
|
||||
|
||||
const testIdentity = randBigint();
|
||||
console.log(testIdentity)
|
||||
|
||||
const username = "admin";
|
||||
const password = process.env.PASSWORD;
|
||||
|
||||
describe("Endpoints should all work hopefully", () => {
|
||||
test("It should respond with server info", async () => {
|
||||
@@ -69,8 +68,6 @@ describe("Endpoints should all work hopefully", () => {
|
||||
.catch((error) => console.warn("POST /room/add - " + error));
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("It should return the room with the given id", async () => {
|
||||
await request(_app)
|
||||
.get(`/api/room/${roomByIdTest}`)
|
||||
@@ -85,11 +82,7 @@ describe("Endpoints should all work hopefully", () => {
|
||||
.catch((error) => pp("GET /api/room/:roomId - " + error, "error"));
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("It should return all rooms", async () => {
|
||||
const username = "admin";
|
||||
const password = process.env.PASSWORD;
|
||||
const base64Credentials = Buffer.from(`${username}:${password}`).toString(
|
||||
"base64"
|
||||
);
|
||||
@@ -100,7 +93,7 @@ describe("Endpoints should all work hopefully", () => {
|
||||
.then((res) => {
|
||||
try {
|
||||
expect(res.status).toEqual(200);
|
||||
expect(typeof res.body).toEqual("object")
|
||||
expect(typeof res.body).toEqual("object");
|
||||
expect(res.body[0].name).toEqual(room.roomName);
|
||||
} catch (error) {
|
||||
pp("GET /api/rooms - " + error, "error");
|
||||
@@ -109,57 +102,10 @@ describe("Endpoints should all work hopefully", () => {
|
||||
.catch((error) => pp("GET /api/rooms - " + error, "error"));
|
||||
});
|
||||
|
||||
|
||||
|
||||
// test("It should return all claim codes", async () => {
|
||||
// const username = "admin";
|
||||
// const password = process.env.PASSWORD;
|
||||
// const base64Credentials = Buffer.from(`${username}:${password}`).toString(
|
||||
// "base64"
|
||||
// );
|
||||
// await request(_app)
|
||||
// .get("/logclaimcodes")
|
||||
// .set("Authorization", `Basic ${base64Credentials}`)
|
||||
// .then((res) => {
|
||||
// try {
|
||||
// // TODO check an array is 4 words - with a seperator between - use split
|
||||
// // push claim codes to an empty array and use one of those for the /join instead
|
||||
// testCode = res.body[0].claimcode
|
||||
// expect(res.body[0].claimcode.split('-').length).toEqual(4)
|
||||
// expect(res.status).toEqual(401);
|
||||
// expect(res.body.length).toBeGreaterThan(0);
|
||||
// } catch (error) {
|
||||
// pp("GET /logclaimcodes - " + error, "error");
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => pp("GET /logclaimcodes - " + error, "error"));
|
||||
// });
|
||||
|
||||
// const joinTest = {
|
||||
// code: testCode,
|
||||
// idc: testIdentity,
|
||||
// };
|
||||
|
||||
// test("It should add a users identity to the rooms the claim code is associated with", async () => {
|
||||
// await request(_app)
|
||||
// .post("/join")
|
||||
// .send(joinTest)
|
||||
// .then((res) => {
|
||||
// try {
|
||||
// expect(res.statusCode).toEqual(200);
|
||||
// expect(res.body.status).toEqual("valid");
|
||||
// } catch (error) {
|
||||
// pp("POST /join - " + error, "error");
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => pp("POST /join - " + error, "error"));
|
||||
// });
|
||||
|
||||
|
||||
test("It should return all claim codes and add a user's identity to the rooms the claim code is associated with", async () => {
|
||||
const username = "admin";
|
||||
const password = process.env.PASSWORD;
|
||||
const base64Credentials = Buffer.from(`${username}:${password}`).toString("base64");
|
||||
const base64Credentials = Buffer.from(`${username}:${password}`).toString(
|
||||
"base64"
|
||||
);
|
||||
|
||||
await request(_app)
|
||||
.get("/logclaimcodes")
|
||||
@@ -168,14 +114,13 @@ describe("Endpoints should all work hopefully", () => {
|
||||
.then(async (res) => {
|
||||
try {
|
||||
testCode = res.body[0].claimcode;
|
||||
expect(testCode.split('-').length).toEqual(4);
|
||||
expect(testCode.split("-").length).toEqual(4);
|
||||
expect(res.status).toEqual(401);
|
||||
expect(res.body.length).toBeGreaterThan(0);
|
||||
|
||||
|
||||
const joinTest = {
|
||||
code: testCode,
|
||||
idc: testIdentity
|
||||
idc: testIdentity,
|
||||
};
|
||||
|
||||
await request(_app)
|
||||
@@ -186,21 +131,19 @@ describe("Endpoints should all work hopefully", () => {
|
||||
expect(res.body.status).toEqual("valid");
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in test: ', error);
|
||||
console.error("Error in test: ", error);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error in request: ', error);
|
||||
console.error("Error in request: ", error);
|
||||
});
|
||||
});
|
||||
console.log(testIdentity);
|
||||
|
||||
test("It should return all rooms associated with the given identity", async () => {
|
||||
await request(_app)
|
||||
.get(`/api/rooms/${testIdentity}`)
|
||||
.then((res) => {
|
||||
.get(`/api/rooms/${testIdentity}`)
|
||||
.then((res) => {
|
||||
try {
|
||||
console.log(res.body);
|
||||
expect(res.statusCode).toEqual(200);
|
||||
} catch (error) {
|
||||
pp("GET /api/rooms/:idc - " + error, "error");
|
||||
@@ -208,4 +151,83 @@ describe("Endpoints should all work hopefully", () => {
|
||||
})
|
||||
.catch((error) => pp("GET /api/rooms/:idc - " + error, "error"));
|
||||
});
|
||||
|
||||
test("It should send a message to all rooms", async () => {
|
||||
const message = {
|
||||
message: "Test message",
|
||||
};
|
||||
const base64Credentials = Buffer.from(`${username}:${password}`).toString(
|
||||
"base64"
|
||||
);
|
||||
await request(_app)
|
||||
.post("/admin/message")
|
||||
.set("Authorization", `Basic ${base64Credentials}`)
|
||||
.send(message)
|
||||
.then((res) => {
|
||||
try {
|
||||
expect(res.statusCode).toEqual(200);
|
||||
expect(res.body).toEqual({ message: "Messages sent to all rooms" });
|
||||
} catch (error) {
|
||||
pp("POST /admin/message - " + error, "error");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return the messages for a given room", async () => {
|
||||
await request(_app)
|
||||
.get(`/api/room/${roomByIdTest}/messages`)
|
||||
.then((res) => {
|
||||
try {
|
||||
expect(res.statusCode).toEqual(200);
|
||||
expect(res.body.length).toBeGreaterThan(0);
|
||||
} catch (error) {
|
||||
pp("GET /api/messages/:roomId - " + error, "error");
|
||||
}
|
||||
})
|
||||
.catch((error) => pp("GET /api/messages/:roomId - " + error, "error"));
|
||||
});
|
||||
});
|
||||
|
||||
// test("It should return all claim codes", async () => {
|
||||
// const username = "admin";
|
||||
// const password = process.env.PASSWORD;
|
||||
// const base64Credentials = Buffer.from(`${username}:${password}`).toString(
|
||||
// "base64"
|
||||
// );
|
||||
// await request(_app)
|
||||
// .get("/logclaimcodes")
|
||||
// .set("Authorization", `Basic ${base64Credentials}`)
|
||||
// .then((res) => {
|
||||
// try {
|
||||
// // TODO check an array is 4 words - with a seperator between - use split
|
||||
// // push claim codes to an empty array and use one of those for the /join instead
|
||||
// testCode = res.body[0].claimcode
|
||||
// expect(res.body[0].claimcode.split('-').length).toEqual(4)
|
||||
// expect(res.status).toEqual(401);
|
||||
// expect(res.body.length).toBeGreaterThan(0);
|
||||
// } catch (error) {
|
||||
// pp("GET /logclaimcodes - " + error, "error");
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => pp("GET /logclaimcodes - " + error, "error"));
|
||||
// });
|
||||
|
||||
// const joinTest = {
|
||||
// code: testCode,
|
||||
// idc: testIdentity,
|
||||
// };
|
||||
|
||||
// test("It should add a users identity to the rooms the claim code is associated with", async () => {
|
||||
// await request(_app)
|
||||
// .post("/join")
|
||||
// .send(joinTest)
|
||||
// .then((res) => {
|
||||
// try {
|
||||
// expect(res.statusCode).toEqual(200);
|
||||
// expect(res.body.status).toEqual("valid");
|
||||
// } catch (error) {
|
||||
// pp("POST /join - " + error, "error");
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => pp("POST /join - " + error, "error"));
|
||||
// });
|
||||
|
||||
Reference in New Issue
Block a user