zkt26/z2/backend/app.js
2026-03-31 15:44:11 +02:00

226 lines
6.2 KiB
JavaScript

const express = require('express');
const mysql = require('mysql2/promise');
const bcrypt = require('bcryptjs');
const session = require('express-session');
const path = require('path');
require('dotenv').config({ path: path.join(__dirname, '../.env') });
const app = express();
const FRONTEND_DIR = path.join(__dirname, '../frontend');
const pool = mysql.createPool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}));
app.get('/', (req, res) => {
if (req.session.user) {
return res.redirect('/index.html');
}
res.sendFile(path.join(FRONTEND_DIR, 'login.html'));
});
app.get('/register', (req, res) => {
res.sendFile(path.join(FRONTEND_DIR, 'register.html'));
});
app.get('/index.html', (req, res) => {
if (!req.session.user) {
return res.redirect('/');
}
res.sendFile(path.join(FRONTEND_DIR, 'index.html'));
});
app.post('/register', async (req, res) => {
const { username, password, password2 } = req.body;
if (!username || !password || !password2) {
return res.redirect('/register.html?error=' + encodeURIComponent('Vyplň všetky polia'));
}
if (password !== password2) {
return res.redirect('/register.html?error=' + encodeURIComponent('Heslá sa nezhodujú'));
}
try {
const hashedPassword = await bcrypt.hash(password, 10);
await pool.execute(
'INSERT INTO users (username, password) VALUES (?, ?)',
[username, hashedPassword]
);
return res.redirect('/');
} catch (err) {
console.error(err);
return res.redirect('/register.html?error=' + encodeURIComponent('Používateľ už existuje'));
}
});
app.post('/login', async (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res.redirect('/?error=Vyplň%20všetky%20polia');
}
try {
const [rows] = await pool.execute(
'SELECT * FROM users WHERE username = ?',
[username]
);
const row = rows[0];
if (!row) {
return res.redirect('/?error=Zlé%20meno%20alebo%20heslo');
}
const result = await bcrypt.compare(password, row.password);
if (!result) {
return res.redirect('/?error=Zlé%20meno%20alebo%20heslo');
}
req.session.user = {
id: row.id,
username: row.username
};
return res.redirect('/index.html');
} catch (err) {
console.error(err);
return res.redirect('/?error=Chyba%20databázy');
}
});
app.post('/logout', (req, res) => {
req.session.destroy(() => {
res.redirect('/');
});
});
app.get('/api/me', (req, res) => {
if (!req.session.user) {
return res.status(401).json({ error: 'Neprihlásený používateľ' });
}
res.json(req.session.user);
});
app.get('/api/tasks', async (req, res) => {
if (!req.session.user) {
return res.status(401).json({ error: 'Neprihlásený používateľ' });
}
try {
const [rows] = await pool.execute(
'SELECT * FROM tasks WHERE user_id = ? ORDER BY deadline ASC',
[req.session.user.id]
);
res.json(rows);
} catch (err) {
console.error(err);
return res.status(500).json({ error: 'Chyba pri načítaní úloh' });
}
});
app.post('/api/tasks', async (req, res) => {
if (!req.session.user) {
return res.status(401).json({ error: 'Neprihlásený používateľ' });
}
const { title, description, deadline } = req.body;
if (!title || !description || !deadline) {
return res.status(400).json({ error: 'Vyplň všetky polia' });
}
try {
const [result] = await pool.execute(
'INSERT INTO tasks (user_id, title, description, deadline) VALUES (?, ?, ?, ?)',
[req.session.user.id, title, description, deadline]
);
const [rows] = await pool.execute(
'SELECT * FROM tasks WHERE id = ?',
[result.insertId]
);
res.json(rows[0]);
} catch (err) {
console.error(err);
return res.status(500).json({ error: 'Chyba pri ukladaní úlohy' });
}
});
app.delete('/api/tasks/:id', async (req, res) => {
if (!req.session.user) {
return res.status(401).json({ error: 'Neprihlásený používateľ' });
}
try {
await pool.execute(
'DELETE FROM tasks WHERE id = ? AND user_id = ?',
[req.params.id, req.session.user.id]
);
res.json({ success: true });
} catch (err) {
console.error(err);
return res.status(500).json({ error: 'Chyba pri mazaní úlohy' });
}
});
app.patch('/api/tasks/:id/toggle', async (req, res) => {
if (!req.session.user) {
return res.status(401).json({ error: 'Neprihlásený používateľ' });
}
const { status } = req.body;
try {
await pool.execute(
'UPDATE tasks SET status = ? WHERE id = ? AND user_id = ?',
[status ? 1 : 0, req.params.id, req.session.user.id]
);
res.json({ success: true });
} catch (err) {
console.error(err);
return res.status(500).json({ error: 'Chyba pri zmene stavu úlohy' });
}
});
app.use(express.static(FRONTEND_DIR));
const PORT = process.env.PORT || 3000;
app.listen(PORT, async () => {
try {
const connection = await pool.getConnection();
console.log('Pripojenie na MySQL úspešné.');
connection.release();
} catch (err) {
console.error('Nepodarilo sa pripojiť na MySQL:', err.message);
}
console.log(`Server beží na http://localhost:${PORT}`);
});