Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ dist-ssr
*.sw?

mongo
mysql

.env
18 changes: 14 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@ services:
ports:
- "3000:3000"
depends_on:
- mongodb
- mariadb
environment:
- DB_HOST=mariadb
- DB_USER=elliptical
- DB_PASS=yourpassword
- DB_NAME=elliptical

mongodb:
mariadb:
restart: always
image: mongo
image: mariadb:latest
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=elliptical
- MYSQL_USER=elliptical
- MYSQL_PASSWORD=yourpassword
volumes:
- ./mongo:/data/db
- ./mysql:/var/lib/mysql
132 changes: 45 additions & 87 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,11 @@
import "dotenv/config"
import { v4 as uuid } from "uuid"
import { build, createServer as createViteServer } from "vite"

import { createInterface } from "node:readline"
import path from "node:path"
import url from "node:url"

import { io, app, server } from "./server/host.js"
import { io, server } from "./server/host.js"
import { executeUserInput } from "./server/adminhandler.js"
import { get, getroom } from "./server/functions.js"
import { rooms, adminpass, reports, initializeDB } from "./server/mongo.js"
import { context } from "./server/context.js"

// Initalize server stuff
const __dirname = url.fileURLToPath(new URL("./", import.meta.url))


// frontend
if (process.argv.includes("--dev")) {
// if dev mode start vite server
const vite = await createViteServer({
server: { middlewareMode: "html" },
})
app.use(vite.middlewares)
console.log("✅ Vite development server served with middleware")
} else {
// prod, serve from dist
console.log("🔁 Building for production...")
await build()
app.use(express.static("dist"))
app.use((req, res) =>
res.sendFile(path.join(__dirname, "dist", "index.html"))
)
console.log("✅ Production build served from dist")
}
import { pool } from "./server/db.js"

// Handle socket.io events
io.on("connection", async (socket) => {
Expand Down Expand Up @@ -70,18 +43,9 @@ io.on("connection", async (socket) => {
} else {
const id = uuid()

await rooms.updateOne(
{
roomid,
},
{
$push: {
messages: {
message,
msgid: id,
},
},
}
const [result] = await pool.execute(
"INSERT INTO messages (room_id, user_id, content, message_uuid) VALUES (?, ?, ?, ?)",
[roomid, socket.id, message, id]
)

io.emit("message", {
Expand All @@ -98,7 +62,10 @@ io.on("connection", async (socket) => {
const messageIncludesBlockedTerm = context.BLOCKED.some((term) =>
room.title.replaceAll(" ", "").toLowerCase().includes(term)
)
const roomCount = await rooms.countDocuments({ private: false })
const [rows] = await pool.execute(
"SELECT COUNT(*) as count FROM rooms WHERE is_private = 0"
)
const roomCount = rows[0].count

if (messageIncludesBlockedTerm)
socket.emit("event", {
Expand All @@ -124,17 +91,15 @@ io.on("connection", async (socket) => {
else {
const id = uuid()

await rooms.insertOne({
title: room.title,
roomid: id,
private: room.private && !!room.code,
...(room.private && room.code
? {
code: room.code,
}
: {}),
messages: [],
})
const [result] = await pool.execute(
"INSERT INTO rooms (room_uuid, name, is_private, access_code) VALUES (?, ?, ?, ?)",
[
id,
room.title,
room.private && !!room.code ? 1 : 0,
room.code || null,
]
)

if (room.private && room.code)
socket.emit("room", {
Expand All @@ -154,14 +119,20 @@ io.on("connection", async (socket) => {

socket.on("join private", async (code) => {
try {
const room = await rooms.findOne({ code })

room.id = room.roomid

delete room._id
delete room.roomid
const [rows] = await pool.execute(
"SELECT * FROM rooms WHERE access_code = ?",
[code]
)

socket.emit("room", room)
if (rows.length > 0) {
const room = rows[0]
socket.emit("room", {
title: room.name,
id: room.room_uuid,
private: true,
code: room.access_code,
})
}
} catch {} // Room does not exist
})

Expand All @@ -185,20 +156,16 @@ io.on("connection", async (socket) => {
socket.on("report msg", async (msg) => {
try {
// Check if report already exists
const existingReport = await reports.findOne({
msgid: msg.msgid,
roomid: msg.roomid,
})

if (!existingReport) {
// Only insert if no existing report found
await reports.insertOne({
msgid: msg.msgid,
roomid: msg.roomid,
message: msg.message,
timestamp: new Date(),
})
const [existing] = await pool.execute(
"SELECT id FROM reports WHERE message_uuid = ? AND room_uuid = ?",
[msg.msgid, msg.roomid]
)

if (existing.length === 0) {
await pool.execute(
"INSERT INTO reports (message_uuid, room_uuid, message_content, reported_at) VALUES (?, ?, ?, NOW())",
[msg.msgid, msg.roomid, msg.message]
)
console.log("📝 New report added:", msg)
}

Expand All @@ -215,18 +182,11 @@ io.on("connection", async (socket) => {
else console.log("❌ Invalid admin password attempt: " + msg.adminpass)
})

socket.on("passchange", (msg) => {
socket.on("passchange", async (msg) => {
if (msg.adminpass.includes(context.PASSWORD)) {
adminpass.updateOne(
{
id: "admin",
},
{
$set: {
password: msg.newpass,
},
}
)
await pool.execute("UPDATE admin_settings SET password = ?", [
msg.newpass,
])

context.PASSWORD = msg.newpass
socket.emit("event", {
Expand All @@ -250,8 +210,6 @@ io.on("connection", async (socket) => {
})
})

await initializeDB()

// Start the server
server.listen(3000, () =>
console.log("✅ Elliptical server running at http://localhost:3000")
Expand Down
Loading