110 lines
3.6 KiB
JavaScript
110 lines
3.6 KiB
JavaScript
|
require('dotenv').config();
|
||
|
|
||
|
const postgres = require('postgres');
|
||
|
const express = require('express');
|
||
|
const app = express();
|
||
|
const Hashids = require('hashids');
|
||
|
const expressws = require('express-ws');
|
||
|
const { generateKey } = require('crypto');
|
||
|
const { promisify } = require('util');
|
||
|
const multer = require('multer');
|
||
|
const storage = multer.diskStorage({
|
||
|
destination: 'uploads/',
|
||
|
filename: async (req, file, cb) => {
|
||
|
const key = (await promisify(generateKey)('hmac', {length: 64})).export().toString('hex');
|
||
|
cb(null, key);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
const upload = multer({ storage: storage, fileFilter: (req, file, cb) => {
|
||
|
if (!imageFormats.includes(file.mimetype)) return cb(null, false);
|
||
|
cb(null, true);
|
||
|
}});
|
||
|
|
||
|
const imageFormats = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', 'image/tiff', 'image/webp', 'image/bmp', 'image/avif', 'image/vnd.microsoft.icon'];
|
||
|
|
||
|
const idLength = 6;
|
||
|
const hashids = new Hashids('chartmaker', idLength);
|
||
|
|
||
|
const port = process.env.PORT || 5252;
|
||
|
const sql = postgres(`postgres://${process.env.DB_USER || 'chartmaker'}:${process.env.DB_PASS}@${process.env.DB_HOST || 'localhost'}:${process.env.DB_PORT || '5432'}/${process.env.DB_NAME || 'chartmaker'}`);
|
||
|
|
||
|
expressws(app);
|
||
|
|
||
|
app.use((req, res, next) => {
|
||
|
res = res.setHeader('Access-Control-Allow-Origin', '*');
|
||
|
next();
|
||
|
});
|
||
|
|
||
|
app.post('/create', async (req, res) => {
|
||
|
const [id] = await sql`SELECT id FROM charts ORDER BY id DESC LIMIT 1`;
|
||
|
let newid = (id || 0) + 1;
|
||
|
|
||
|
let body = req.body || {};
|
||
|
await sql`
|
||
|
INSERT INTO charts VALUES (${newid}, ${body.name || ''}, ${body.leftText || ''}, ${body.rightText || ''}, ${body.topText || ''}, ${body.bottomText || ''})
|
||
|
`;
|
||
|
|
||
|
res.status(200).send(hashids.encode(newid));
|
||
|
});
|
||
|
|
||
|
app.post('/add', upload.single('icon'), async (req, res) => {
|
||
|
if (!req.body) return res.sendStatus(401);
|
||
|
if (!req.body.id) return res.status(401).send('Supply a chart ID!');
|
||
|
if (!req.body.name) return res.status(401).send('Supply a name!');
|
||
|
if (!req.body.x || !req.body.y) return res.status(401).send('Supply a position!');
|
||
|
const id = hashids.decode(req.body.id);
|
||
|
if (!id[0]) return res.status(401).send('Invalid chart ID!');
|
||
|
let [exists] = await sql`
|
||
|
SELECT id FROM charts WHERE id = ${id[0]}
|
||
|
`;
|
||
|
if (!exists) return res.status(401).send('Chart doesn\'t exist!');
|
||
|
await sql`
|
||
|
INSERT INTO images VALUES (${id[0]}, ${req.file.filename}, ${req.body.name}, ${req.body.x}, ${req.body.y})
|
||
|
`;
|
||
|
res.sendStatus(200);
|
||
|
});
|
||
|
|
||
|
app.ws('/connect', async (ws, req) => {
|
||
|
if (!req.query.id) return ws.close(1008, 'Supply a chart ID in the query!');
|
||
|
const id = hashids.decode(req.query.id)[0];
|
||
|
if (!id) return ws.close(1008, 'Invalid chart ID!');
|
||
|
let [chart] = await sql`
|
||
|
SELECT * FROM charts WHERE id = ${id}
|
||
|
`;
|
||
|
if (!chart) return ws.close(1008, 'Chart doesn\'t exist!');
|
||
|
|
||
|
await ws.send(JSON.stringify({name: chart.name, leftText: chart.leftText, rightText: chart.rightText, topText: chart.topText, bottomText: chart.bottomText}));
|
||
|
|
||
|
await ws.send(JSON.stringify((await sql`SELECT * FROM images WHERE id = ${id}`).map(i => {return {name: i.name, x: i.x, y: i.y, file: i.filepath}})));
|
||
|
|
||
|
// and now send new scrunklys whenever they appear
|
||
|
// TODO
|
||
|
});
|
||
|
|
||
|
(async () => {
|
||
|
await sql`
|
||
|
CREATE TABLE IF NOT EXISTS charts (
|
||
|
id int PRIMARY KEY,
|
||
|
name text,
|
||
|
leftText text,
|
||
|
rightText text,
|
||
|
topText text,
|
||
|
bottomText text
|
||
|
)
|
||
|
`;
|
||
|
await sql`
|
||
|
CREATE TABLE IF NOT EXISTS images (
|
||
|
id int PRIMARY KEY,
|
||
|
filepath text,
|
||
|
name text,
|
||
|
x real,
|
||
|
y real
|
||
|
)
|
||
|
`;
|
||
|
|
||
|
app.listen(port, () => {
|
||
|
console.log(`listening on ${port}`);
|
||
|
});
|
||
|
})();
|