AnoPaper/index.js
2023-04-21 13:18:00 +03:00

133 lines
3.4 KiB
JavaScript

/*
Copyright (c) 2023 artegoser (Artemy Egorov)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const sha3 = require("js-sha3").sha3_512;
const express = require("express");
const bodyParser = require("body-parser");
const isValidNote = require("./note_validator");
const fs = require("fs");
const path = require("path");
const cryptojs = require("crypto-js");
const { Server } = require("socket.io");
const rateLimit = require("express-rate-limit");
require("dotenv").config();
const app = express(),
server = require("http").createServer(app),
io = new Server().listen(server);
const limiter = rateLimit({
windowMs: 24 * 60 * 60 * 1000, // one day limit
max: 10,
standardHeaders: true,
legacyHeaders: false,
});
if (!fs.existsSync("./notes")) {
fs.mkdirSync("./notes");
}
io.on("connection", (socket) => {
socket.on("nameChanged", ({ name, room }) => {
socket.to(room).emit("nameChanged", {
name,
});
});
socket.on("textChanged", ({ text, room }) => {
socket.to(room).emit("textChanged", {
text,
});
});
socket.on("joinRoom", (room) => {
let rooms = Array.from(io.sockets.adapter.sids.get(socket.id));
for (let room of rooms) {
if (socket.id != room) {
socket.leave(room);
}
}
socket.join(room);
socket.to(room).emit("roomJoined");
});
socket.on("leaveRoom", () => {
for (let room of rooms) {
if (socket.id != room) {
socket.leave(room);
}
}
});
socket.on("broadcastSync", ({ data, room }) => {
socket.to(room).emit("broadcastSync", data);
});
});
app.use(bodyParser.json());
app.post("/publish", limiter, function (req, res) {
if (isValidNote(req.body)) {
let hash = sha3(JSON.stringify(req.body));
req.body.time = Date.now();
req.body.pub = true;
req.body.pubTime = req.body.time;
try {
fs.writeFileSync(
`./notes/${hash}.json`,
cryptojs.AES.encrypt(
JSON.stringify(req.body),
process.env.KEY
).toString()
);
res.send({ id: hash });
} catch {
res.status(500).send("Failed to write file");
}
} else {
res.status(403).send("Invalid body!");
}
});
app.get("/get-note/:delorno/:id", function (req, res) {
let path = `./notes/${req.params.id}.json`;
try {
let data = JSON.parse(
cryptojs.AES.decrypt(
fs.readFileSync(path, "utf-8"),
process.env.KEY
).toString(cryptojs.enc.Utf8)
);
res.send(data);
if (req.params.delorno === "del") fs.unlinkSync(path);
} catch {
res.status(404).send("There is no such note");
}
});
app.use(express.static("dist"));
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "./dist", "index.html"));
});
server.listen(process.env.PORT, () => {
console.log(`Listening on port ${process.env.PORT}`);
});