diff --git a/package-lock.json b/package-lock.json index 2db4dde..02df99c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "body-parser": "^1.20.2", "cors": "^2.8.5", "discreetly-claimcodes": "^1.1.3", - "discreetly-interfaces": "^0.1.17", + "discreetly-interfaces": "^0.1.21", "dotenv": "^16.3.1", "express": "^4.18.2", "mongodb": "^5.7.0", @@ -1887,9 +1887,9 @@ "integrity": "sha512-2QnlhYUPIGLl11XgxIxl6ZKIJZoS2T1ABIHbqjBbec0YYQ2qfWZ7JWH53OZm0mqeO8Dbjon5zK3YNoGiuYJ1Gg==" }, "node_modules/discreetly-interfaces": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/discreetly-interfaces/-/discreetly-interfaces-0.1.17.tgz", - "integrity": "sha512-sXS/f/oYKZMQDR4tJSmuBfyCyE4f5iO6PwEKEHAMCDH7AklQphKR9RPnpLa4DFBCIznayzKipZxmT8zBHOSk6w==", + "version": "0.1.21", + "resolved": "https://registry.npmjs.org/discreetly-interfaces/-/discreetly-interfaces-0.1.21.tgz", + "integrity": "sha512-REQ+QUAWprx7j2RPMZi+55Xlfr9pgUHAHnQ9V14FMjnhE6iXl4SWHvg5nskU5EKxrMn2C6AhEd/Aj1T4uwMWHA==", "dependencies": { "poseidon-lite": "^0.2.0", "rlnjs": "^3.1.4" diff --git a/package.json b/package.json index f3ea890..c997642 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "body-parser": "^1.20.2", "cors": "^2.8.5", "discreetly-claimcodes": "^1.1.3", - "discreetly-interfaces": "^0.1.17", + "discreetly-interfaces": "^0.1.21", "dotenv": "^16.3.1", "express": "^4.18.2", "mongodb": "^5.7.0", @@ -59,4 +59,4 @@ "ts-node": "^10.9.1", "typescript": "^5.1.6" } -} \ No newline at end of file +} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 67d6f18..c68bda0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -33,7 +33,7 @@ model ClaimCodes { model Messages { id String @id @default(auto()) @map("_id") @db.ObjectId - messageID String // Internal Nullifier + messageId String // Internal Nullifier message String timeStamp DateTime @default(now()) roomId String diff --git a/src/crypto/verifier.ts b/src/crypto/verifier.ts index d898cb0..0f556c2 100644 --- a/src/crypto/verifier.ts +++ b/src/crypto/verifier.ts @@ -11,7 +11,7 @@ async function verifyProof(msg: MessageI, room: RoomI): Promise { const timestamp = Date.now(); const rateLimit = room.rateLimit ? room.rateLimit : 1000; const currentEpoch = Math.floor(timestamp / rateLimit); - const rlnIdentifier = BigInt(msg.room); + const rlnIdentifier = BigInt(msg.roomId); const msgHash = str2BigInt(msg.message); // Check that the epoch falls within the range for the room const epoch = BigInt(msg.epoch); diff --git a/src/data/db.ts b/src/data/db.ts index 4b7d280..716a4c5 100644 --- a/src/data/db.ts +++ b/src/data/db.ts @@ -10,17 +10,32 @@ import type { ClaimCodeT } from 'discreetly-claimcodes'; const prisma = new PrismaClient(); + +interface CodeStatus { + claimed: boolean; + roomIds: string[]; +} + +interface ClaimCode { + roomIds: string[]; +} + export function getRoomByID(id: string): Promise { - return prisma.rooms - .findUnique({ - where: { - roomId: id - } - }) - .then((room) => { - //TODO NEED TO FILTER OUT CLAIMCODE REFERENCES - return room; - }) + return prisma.rooms.findUnique({ + where: { + roomId: id + }, + select: { + id: true, + roomId: true, + name: true, + identities: true, + rateLimit: true, + userMessageLimit: true, + } + }).then((room) => { + return room + }) .catch((err) => { console.error(err); throw err; // Add this line to throw the error @@ -28,7 +43,10 @@ export function getRoomByID(id: string): Promise { } export function getRoomsByIdentity(identity: string): RoomI[] { - // TODO Need to create a system here where the client needs to provide a proof they know the secrets to some Identity Commitment with a unix epoch time stamp to prevent replay attacks + /* TODO Need to create a system here where the client needs to provide a + proof they know the secrets to some Identity Commitment with a unix epoch + time stamp to prevent replay attacks + */ prisma.rooms .findMany({ where: { @@ -100,6 +118,36 @@ export function createRoom( prisma.rooms .upsert(roomData) - .then(() => {}) + .then(() => { }) .catch((err) => console.error(err)); } + +export function findClaimCode(code: string): Promise { + return prisma.claimCodes.findUnique({ + where: { claimcode: code }, + }); +} + +export function updateClaimCode(code: string): Promise { + return prisma.claimCodes.update({ + where: { claimcode: code }, + data: { claimed: true }, + }); +} + +export function updateRoomIdentities(idc: string, roomIds: string[]): Promise { + return prisma.rooms.updateMany({ + where: { id: { in: roomIds } }, + data: { + identities: { + push: idc + }, + }, + }); +} + +export function findUpdatedRooms(roomIds: string[]): Promise { + return prisma.rooms.findMany({ + where: { id: { in: roomIds } }, + }); +} diff --git a/src/data/messages.ts b/src/data/messages.ts new file mode 100644 index 0000000..f8986a5 --- /dev/null +++ b/src/data/messages.ts @@ -0,0 +1,59 @@ +import { getRoomByID } from "./db"; +import { PrismaClient } from '@prisma/client' +import { MessageI } from 'discreetly-interfaces' + + +const prisma = new PrismaClient(); + + +// const testRoomId = '20945462742745557191488383979949684808523754877925170533224967224808050898610' +// const testIdentity = '14190528236246017918200035567042171677174421028127319624115381263123381401333' +// const testMessage = { +// meesage: "New Message", +// messageId: '92047824095782849075874', +// proof: genProof(await getRoomByID(testRoomId), testIdentity, 1), +// roomId: testRoomId +// } + +function updateRoom(roomId: string, message: MessageI): Promise { + return prisma.rooms.update({ + where: { + roomId: roomId + }, + data: { + epochs: { + create: { + epoch: +message.epoch.toString(), + messages: { + create: { + message: message.message, + messageId: message.messageId, + proof: JSON.stringify(message.proof), + roomId: roomId + } + } + } + } + } + }); +} + +export function createMessage(roomId: string, message: MessageI) { + getRoomByID(roomId) + .then(room => { + if (room) { + updateRoom(roomId, message) + .then(roomToUpdate => { + console.log(roomToUpdate); + }) + .catch(error => { + console.error(`Error updating room: ${error}`); + }); + } else { + console.log("Room not found"); + } + }) + .catch(error => { + console.error(`Error getting room: ${error}`); + }); +} diff --git a/src/data/mock.ts b/src/data/mock.ts index d9f9540..6cf64d7 100644 --- a/src/data/mock.ts +++ b/src/data/mock.ts @@ -41,7 +41,7 @@ export default function Mock(io: SocketIOServer) { setInterval(() => { const message: MessageI = { id: faker.number.bigInt().toString(), - room: BigInt('20945462742745557191488383979949684808523754877925170533224967224808050898610'), + roomId: BigInt('20945462742745557191488383979949684808523754877925170533224967224808050898610'), message: picker.pick(), timestamp: Date.now().toString(), epoch: Math.floor(Date.now() / 10000) diff --git a/src/endpoints/index.ts b/src/endpoints/index.ts index 304bc55..f857ff2 100644 --- a/src/endpoints/index.ts +++ b/src/endpoints/index.ts @@ -2,7 +2,7 @@ import type { Express } from 'express'; import { PrismaClient } from '@prisma/client'; import { serverConfig } from '../config/serverConfig'; import { pp } from '../utils.js'; -import { getRoomByID, getRoomsByIdentity } from '../data/db'; +import { getRoomByID, getRoomsByIdentity, findClaimCode, updateClaimCode, updateRoomIdentities, findUpdatedRooms } from '../data/db'; import { RoomI, genId } from 'discreetly-interfaces'; // TODO! Properly handle authentication for admin endpoints @@ -62,81 +62,37 @@ export function initEndpoints(app: Express) { res.json(getRoomsByIdentity(req.params.idc)); }); - app.post('/join', (req, res) => { - interface JoinRequestBody { - code: string; - idc: string; - } - console.log(req.body); - const { code, idc } = req.body as JoinRequestBody; + app.post("/join", (req, res) => { + const { code, idc } = req.body; - pp(`Express[/join]: claiming code: ${code}`); - - prisma.claimCodes - .findUnique({ - where: { - claimcode: code - } - }) - .then((codeStatus: { claimed: boolean; roomIds: string[] }) => { - console.log(codeStatus); - if (codeStatus.claimed === false) { - prisma.claimCodes - .update({ - where: { - claimcode: code - }, - data: { - claimed: true - } - }) - .then((claimCode: { roomIds: string[] }) => { + findClaimCode(code) + .then((codeStatus) => { + if (codeStatus && codeStatus.claimed === false) { + return updateClaimCode(code) + .then((claimCode) => { const roomIds = claimCode.roomIds.map((room) => room); - prisma.rooms - .updateMany({ - where: { - roomId: { - in: roomIds - } - }, - data: { - identities: { - push: idc - } - } - }) - .then(async () => { - // return the room name of all the rooms that were updated - const updatedRooms = await prisma.rooms.findMany({ - where: { - id: { - in: roomIds - } - } - }); - res - .status(200) - .json({ status: 'valid', roomIds: updatedRooms.map((room) => room.roomId) }); - }) - .catch((err) => { - console.error(err); - res.status(500).json({ error: 'Internal Server Error' }); + return updateRoomIdentities(idc, roomIds) + .then(() => { + return findUpdatedRooms(roomIds) + .then((updatedRooms: RoomI[]) => { + return res.status(200).json({ + status: "valid", + roomIds: updatedRooms.map((room) => room.roomId), + }); + }); }); - }) - .catch((err) => { - console.error(err); - res.status(500).json({ error: 'Internal Server Error' }); }); } else { - res.status(400).json({ message: 'Claim code already used' }); + res.status(400).json({ message: "Claim code already used" }); } }) - .catch((err) => { + .catch((err: Error) => { console.error(err); - res.status(500).json({ error: 'Internal Server Error' }); + res.status(500).json({ error: "Internal Server Error" }); }); }); + app.post('/room/add', (req, res) => { interface RoomData { password: string; diff --git a/src/server.ts b/src/server.ts index d41b5d9..7b7b562 100644 --- a/src/server.ts +++ b/src/server.ts @@ -7,10 +7,10 @@ import { pp, shim } from './utils'; import mock from './data/mock'; import { websocketSetup as initWebsockets } from './websockets/index'; import { initEndpoints } from './endpoints/index'; +import { createMessage } from './data/messages'; const app = express(); const socket_server = new Server(app); - shim(); app.use(express.json()); diff --git a/src/websockets/index.ts b/src/websockets/index.ts index 406f02f..4ff031c 100644 --- a/src/websockets/index.ts +++ b/src/websockets/index.ts @@ -3,6 +3,7 @@ import { Socket, Server as SocketIOServer } from 'socket.io'; import verifyProof from '../crypto/verifier'; import { getRoomByID } from '../data/db'; import { pp } from '../utils'; +import { createMessage } from '../data/messages'; const userCount: { [key: string]: number; @@ -15,7 +16,7 @@ export function websocketSetup(io: SocketIOServer) { socket.on('validateMessage', (msg: MessageI) => { pp({ 'VALIDATING MESSAGE ID': msg.id.slice(0, 11), 'MSG:': msg.message }); let valid: boolean; - getRoomByID(msg.room.toString()) + getRoomByID(msg.roomId.toString()) .then((room: RoomI) => { if (!room) { pp('INVALID ROOM', 'warn'); @@ -24,6 +25,8 @@ export function websocketSetup(io: SocketIOServer) { verifyProof(msg, room) .then((v) => { valid = v; + createMessage(msg.roomId.toString(), msg); + io.emit('messageBroadcast', msg); }) .catch((err) => { err; @@ -32,7 +35,7 @@ export function websocketSetup(io: SocketIOServer) { pp('INVALID MESSAGE', 'warn'); return; } - io.emit('messageBroadcast', msg); + }) .catch((err) => pp(err, 'error')); });