diff --git a/src/index.ts b/src/index.ts index 3e7ac3b..6caed56 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,11 @@ import { Elysia, t } from 'elysia' import { cors } from '@elysiajs/cors' import { ElysiaWS } from 'elysia/dist/ws' -import { jsonResponse } from './lib/util' +import { getDatabaseConnection, jsonResponse } from './lib/util' import dotenv from 'dotenv' import swagger from '@elysiajs/swagger' +import { berryDashChats, berryDashUserData, users } from './lib/tables' +import { desc, eq } from 'drizzle-orm' import { handler as getVerifyCodeHandler } from './routes/get-verify-code' @@ -39,6 +41,7 @@ import { handler as berryDashAccountChangeUsernamePostHandler } from './routes/b import { handler as berryDashAccountChangePasswordPostHandler } from './routes/berrydash/account/change-password/post' import { handler as berryDashAccountSaveGetHandler } from './routes/berrydash/account/save/get' import { handler as berryDashAccountSavePostHandler } from './routes/berrydash/account/save/post' +import { checkAuthorization } from './lib/bd/auth' dotenv.config({ quiet: true }) @@ -61,7 +64,8 @@ const boolNotStr = (name: string) => { const app = new Elysia({ prefix: '/api', websocket: { - idleTimeout: 10 + idleTimeout: 10, + maxPayloadLength: 8192 } }) .use( @@ -87,12 +91,180 @@ const app = new Elysia({ const clients = new Set() app.ws('/ws', { + maxPayloadLength: 10 * 1024 * 1024, open (ws) { clients.add(ws) console.log(ws.id, 'connected') }, - message (ws, message) { + async message (ws, message: any) { console.log('received:', message, 'from', ws.id) + if (message.type) { + if (message.type == 'upload') { + if ( + message.kind && + message.kind == 'chatroom_message' && + message.data && + message.data.content && + message.data.auth + ) { + const dbInfo0 = getDatabaseConnection(0) + const dbInfo1 = getDatabaseConnection(1) + + if (!dbInfo0 || !dbInfo1) + return jsonResponse( + { success: false, message: 'Failed to connect to database' }, + 500 + ) + const { connection: connection0, db: db0 } = dbInfo0 + const { connection: connection1, db: db1 } = dbInfo1 + + const ip = ws.remoteAddress + const authResult = await checkAuthorization( + message.data.auth as string, + db1, + db0, + ip + ) + if (!authResult.valid) return + const userId = authResult.id + const time = Math.floor(Date.now() / 1000) + + const insert = await db1 + .insert(berryDashChats) + .values({ + userId, + content: btoa(message.data.content as string), + timestamp: time + }) + .execute() + + const userData = await db1 + .select({ + legacyHighScore: berryDashUserData.legacyHighScore, + saveData: berryDashUserData.saveData + }) + .from(berryDashUserData) + .where(eq(berryDashUserData.id, userId)) + .limit(1) + .execute() + if (!userData[0]) return + + const userInfo = await db0 + .select({ username: users.username }) + .from(users) + .where(eq(users.id, userId)) + .limit(1) + .execute() + if (!userInfo[0]) return + + let savedata = JSON.parse(userData[0].saveData) + + for (const client of clients) { + client.send( + JSON.stringify({ + for: message.type + ':' + message.kind, + data: { + username: userInfo[0].username, + userId, + content: btoa(message.data.content as string), + id: insert[0].insertId, + icon: savedata?.bird?.icon ?? 1, + overlay: savedata?.bird?.overlay ?? 0, + birdColor: savedata?.settings?.colors?.icon ?? [ + 255, 255, 255 + ], + overlayColor: savedata?.settings?.colors?.overlay ?? [ + 255, 255, 255 + ], + customIcon: savedata?.bird?.customIcon?.selected ?? null + } + }) + ) + } + + connection0.end() + connection1.end() + } + } else if (message.type == 'info_request') { + if (message.kind && message.kind == 'chatroom_messages') { + const dbInfo0 = getDatabaseConnection(0) + const dbInfo1 = getDatabaseConnection(1) + + if (!dbInfo0 || !dbInfo1) + return ws.send( + JSON.stringify({ + for: message.type + ':' + message.kind, + success: false, + message: 'Failed to get messages', + data: null + }) + ) + const { connection: connection0, db: db0 } = dbInfo0 + const { connection: connection1, db: db1 } = dbInfo1 + + const chats = await db1 + .select({ + id: berryDashChats.id, + content: berryDashChats.content, + userId: berryDashChats.userId + }) + .from(berryDashChats) + .limit(50) + .where(eq(berryDashChats.deletedAt, 0)) + .orderBy(desc(berryDashChats.id)) + .execute() + + let mapped: Record[] = [] + for (const chat of chats.reverse()) { + const userData = await db1 + .select({ + legacyHighScore: berryDashUserData.legacyHighScore, + saveData: berryDashUserData.saveData + }) + .from(berryDashUserData) + .where(eq(berryDashUserData.id, chat.userId)) + .limit(1) + .execute() + if (!userData[0]) continue + + const userInfo = await db0 + .select({ username: users.username }) + .from(users) + .where(eq(users.id, chat.userId)) + .limit(1) + .execute() + + let savedata = JSON.parse(userData[0].saveData) + + mapped.push({ + username: userInfo[0].username, + userId: chat.userId, + content: chat.content, + id: chat.id, + icon: savedata?.bird?.icon ?? 1, + overlay: savedata?.bird?.overlay ?? 0, + birdColor: savedata?.settings?.colors?.icon ?? [255, 255, 255], + overlayColor: savedata?.settings?.colors?.overlay ?? [ + 255, 255, 255 + ], + customIcon: savedata?.bird?.customIcon?.selected ?? null + }) + } + + connection0.end() + connection1.end() + + ws.send( + JSON.stringify({ + for: message.type + ':' + message.kind, + success: true, + message: null, + data: mapped + }) + ) + } + } + } }, close (ws) { clients.forEach(client => {