forked from dachan/dach
		
	implemented creation of boards, their listing, admin login and initialization of the database
This commit is contained in:
		
							
								
								
									
										117
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								src/index.js
									
									
									
									
									
								
							@@ -1,14 +1,125 @@
 | 
			
		||||
const express = require('express');
 | 
			
		||||
const settings = require('../settings.json');
 | 
			
		||||
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');
 | 
			
		||||
 | 
			
		||||
const app = express();
 | 
			
		||||
 | 
			
		||||
app.set('views','./public');
 | 
			
		||||
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');
 | 
			
		||||
app.use(express.static('public'));
 | 
			
		||||
app.set('view engine', 'ejs');
 | 
			
		||||
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 }
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
app.get('/', (req, res) => {
 | 
			
		||||
    res.render('index');
 | 
			
		||||
})
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
app.listen(settings.port);
 | 
			
		||||
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("Борда успешно создана");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
app.listen(settings.port, () => {
 | 
			
		||||
    console.log("App started");
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user