]> git.lizzy.rs Git - myplace.git/blob - init.js
Don't expose database port
[myplace.git] / init.js
1 const mongodb = require("mongodb")
2 const cors = require("cors")
3 const morgan = require("morgan")
4 const hcaptcha = require("express-hcaptcha")
5 const express = require("express")
6 const socketIO = require("socket.io")
7 const httpError = require("http-errors")
8 const parseColor = require("color-parse")
9
10 const max_size = 1000
11
12 const app = require("express")()
13 const server = require("http").createServer(app)
14 const mongoClient = new mongodb.MongoClient("mongodb://database:27017/myplace")
15 const io = new socketIO.Server(server)
16
17 const hcaptchaValidate = hcaptcha.middleware.validate(process.env.HCAPTCHA_SECRET_KEY)
18
19 app.use(morgan("tiny"))
20 app.set("view engine", "ejs")
21 app.use(express.static("public"))
22 app.use(express.static("node_modules/qrcode/build"))
23 app.use(express.urlencoded({extended: true}))
24
25 const getRoom = id => mongoClient.db().collection("rooms")
26         .findOne({_id: new mongodb.ObjectID.createFromHexString(id)})
27
28 const parseCoord = (size, max) => {
29         const x = parseInt(size.x)
30         const y = parseInt(size.y)
31
32         if (isNaN(x) || isNaN(y))
33                 return
34
35         if (x < 0 || y < 0)
36                 return
37
38         if (x >= max.x || y >= max.y)
39                 return
40
41         return {x, y}
42 }
43
44 app.get("/", cors(), (req, res) => {
45         res.render("create", {
46                 max_size,
47                 hcaptcha_site_key: process.env.HCAPTCHA_SITE_KEY,
48         })
49 })
50
51 app.get("/room/:id/", (req, res) => getRoom(req.params.id).then(room => {
52         if (!room)
53                 throw httpError(404)
54
55         res.render("room", {id: room._id.toHexString()})
56 }))
57
58 app.use("/create", (req, res, next) => {
59         req.body.token = req.body["h-captcha-response"]
60         next()
61 })
62
63 app.post("/create", hcaptchaValidate, (req, res) => {
64         const timeout = parseInt(req.body.timeout)
65         const size = parseCoord({x: req.body.width, y: req.body.height}, {y: max_size, x: max_size})
66
67         if (isNaN(timeout) || timeout < 0)
68                 throw httpError(400, "Invalid timeout")
69
70         if (!size)
71                 throw httpError(400, "Invalid width or height")
72         
73         mongoClient.db().collection("rooms")
74                 .insertOne({
75                         timeout, size,
76                         data: {},
77                 }).then(result => {
78                         const id = result.insertedId.toHexString()
79                         const link = `${req.protocol}://${req.get("host")}/room/${id}/`
80                         
81                         res.render("created", {id, link})
82                 })
83 })
84
85 io.on("connection", socket => {
86         socket.on("join", id => getRoom(id).then(room => {
87                 if (!room)
88                         return
89
90                 socket.emit("timeout", room.timeout)
91                 socket.emit("size", room.size)
92                 socket.emit("place", room.data)
93                 socket.join(room._id.toHexString())
94         }))
95
96         socket.on("place", ({id, x, y, color}) => getRoom(id).then(room => {
97                 if (!room)
98                         return
99
100                 if (!color || !parseColor(color))
101                         return
102
103                 const pos = parseCoord({x, y}, room.size)
104
105                 if (!pos)
106                         return
107
108                 mongoClient.db().collection("rooms")
109                         .updateOne({_id: room._id},
110                                 {"$set": {[`data.${pos.x}.${pos.y}`]: color}})
111                 io.sockets.in(room._id.toHexString()).emit("place", {[pos.x]: {[pos.y]: color}})
112         }))
113 })
114
115 mongoClient.connect().then(_ => {
116         server.listen(23430, _ => {
117                 const address = server.address()
118                 console.log("Listening on " + address.address + ":" + address.port)
119         })
120 })