2023-10-22 22:39:45 +03:00
|
|
|
|
const express = require('express');
|
|
|
|
|
const settings = require('../settings.json');
|
2023-10-27 18:42:05 +03:00
|
|
|
|
const { Client } = require('pg');
|
|
|
|
|
const session = require('express-session');
|
|
|
|
|
const dotenv = require('dotenv');
|
|
|
|
|
const MemoryStore = require('memorystore')(session);
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
const bcrypt = require('bcryptjs');
|
2023-10-22 22:39:45 +03:00
|
|
|
|
|
|
|
|
|
const app = express();
|
|
|
|
|
|
2023-10-27 18:42:05 +03:00
|
|
|
|
dotenv.config({ path: './web.env' });
|
|
|
|
|
|
|
|
|
|
const db = new Client({
|
|
|
|
|
user: process.env.DB_USER,
|
|
|
|
|
host: "127.0.0.1",
|
|
|
|
|
database: process.env.DB_NAME,
|
|
|
|
|
password: process.env.DB_PASS,
|
|
|
|
|
port: 5432
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
db.connect((error) => {
|
|
|
|
|
if (error) console.log(error);
|
|
|
|
|
else console.log("Database connected");
|
|
|
|
|
db.query('SELECT to_regclass(\'admins\');', (err, res) => {
|
|
|
|
|
if(res.rows[0].to_regclass != "admins") init();
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const init = async () => {
|
|
|
|
|
let initSQL = fs.readFileSync("./database_schematic.pgsql").toString();
|
|
|
|
|
|
|
|
|
|
console.log("No tables found, assuming first run, creating database scheme");
|
|
|
|
|
|
|
|
|
|
db.query(initSQL, (err, res) => {
|
|
|
|
|
if (err) console.log(err);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let adminPassword = Math.random().toString(36).slice(-8);
|
|
|
|
|
let passwordHash = await bcrypt.hash(adminPassword, 8);
|
|
|
|
|
console.log(`Creating admin account with credentials: admin:${adminPassword}`);
|
|
|
|
|
db.query("INSERT INTO priveleges (privelege_name, access_level) VALUES ('admin', 100)");
|
|
|
|
|
db.query("INSERT INTO admins (login, password_hash, privelege_name) VALUES ('admin', $1, 'admin')", [passwordHash])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let tokens = {};
|
|
|
|
|
|
|
|
|
|
app.set('views','/usr/share/dach/public');
|
2023-10-22 22:39:45 +03:00
|
|
|
|
app.use(express.static('public'));
|
|
|
|
|
app.set('view engine', 'ejs');
|
2023-10-27 18:42:05 +03:00
|
|
|
|
app.use(express.urlencoded({ extended: true }))
|
|
|
|
|
app.use(express.json())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.use(session({
|
|
|
|
|
secret: process.env.SESSION_SECRET,
|
|
|
|
|
store: new MemoryStore({
|
|
|
|
|
checkPeriod: 86400000
|
|
|
|
|
}),
|
|
|
|
|
resave: false,
|
|
|
|
|
saveUninitialized: false,
|
|
|
|
|
cookie: { maxAge: 1000*60*60*24 }
|
|
|
|
|
}));
|
2023-10-22 22:39:45 +03:00
|
|
|
|
|
|
|
|
|
app.get('/', (req, res) => {
|
|
|
|
|
res.render('index');
|
2023-10-27 18:42:05 +03:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.get('/api/getBoards', async (req, res) => {
|
|
|
|
|
let queryRes = await db.query('SELECT * FROM boards');
|
|
|
|
|
|
|
|
|
|
res.setHeader('Content-Type', 'application/json');
|
|
|
|
|
res.end(JSON.stringify(queryRes.rows));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.post('/api/login', async (req, res) => {
|
|
|
|
|
const { login, password } = req.body;
|
|
|
|
|
|
|
|
|
|
if (!(login && password)) return res.status(401).send("Не указан логин или пароль");
|
|
|
|
|
|
|
|
|
|
queryRes = await db.query('SELECT * FROM admins WHERE login = $1', [login])
|
|
|
|
|
if (queryRes.rowCount == 0) return res.status(401).send("Такого лоигна нет");
|
|
|
|
|
|
|
|
|
|
let hashedPassword = queryRes.rows[0].password_hash;
|
|
|
|
|
bcrypt.compare(password, hashedPassword, (err, result) => {
|
|
|
|
|
if (!result) return res.status(403).send("Пароли не совпадают");
|
|
|
|
|
let currentSession = req.session;
|
|
|
|
|
currentSession.login = login;
|
|
|
|
|
if (!tokens[login]) {
|
|
|
|
|
let token = Math.random().toString(26).slice(2); // ONLY IN DEV MODE
|
|
|
|
|
tokens[login] = token;
|
|
|
|
|
currentSession.token = token;
|
|
|
|
|
console.log(token);
|
|
|
|
|
}
|
|
|
|
|
res.redirect("/index");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.post('/api/createBoard', async (req, res) => {
|
|
|
|
|
const { boardId, boardName } = req.body;
|
|
|
|
|
let login, token;
|
|
|
|
|
try {
|
|
|
|
|
let currentSession = req.session;
|
|
|
|
|
token = currentSession.token;
|
|
|
|
|
login = currentSession.login;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.log(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (token != tokens[login] || !token) return res.status(403).send("Невалидный токен");
|
|
|
|
|
|
|
|
|
|
console.log(`Admin ${login} is creating new board: ${boardId}, ${boardName}`);
|
|
|
|
|
|
|
|
|
|
let queryRes = await db.query('SELECT * FROM boards WHERE board_id = $1::text', [boardId]);
|
|
|
|
|
if (boardId.length == 0 || boardId.length > 5) return res.status(401).send("Неверный размер URI борды");
|
|
|
|
|
if (boardName.length == 0 || boardName.length > 32) return res.status(401).send("Неверный размер имени борды");
|
|
|
|
|
if (queryRes.rowCount > 0) return res.status(401).send("Такая борда уже существует.");
|
|
|
|
|
|
|
|
|
|
await db.query('INSERT INTO boards (board_id, board_name) VALUES ($1, $2)', [boardId, boardName]);
|
|
|
|
|
return res.status(200).send("Борда успешно создана");
|
|
|
|
|
});
|
2023-10-22 22:39:45 +03:00
|
|
|
|
|
2023-10-27 18:42:05 +03:00
|
|
|
|
app.listen(settings.port, () => {
|
|
|
|
|
console.log("App started");
|
|
|
|
|
});
|