From 8d11439065b177edc52426780ee4e563451f3e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Ut=C4=BE=C3=A1k?= Date: Sun, 22 Mar 2026 11:40:10 +0000 Subject: [PATCH 1/3] backend --- Dockerfile | 12 +++ app.js | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 Dockerfile create mode 100644 app.js diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d76d490 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM node:20-alpine + +WORKDIR /app + +COPY package*.json ./ +RUN npm install + +COPY backend ./backend + +EXPOSE 3000 + +CMD ["node", "backend/app.js"] \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..b04e1e3 --- /dev/null +++ b/app.js @@ -0,0 +1,226 @@ +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}`); +}); \ No newline at end of file From a0544835dfdaa4647703769522cc29826ccf44c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Ut=C4=BE=C3=A1k?= Date: Sun, 22 Mar 2026 11:44:48 +0000 Subject: [PATCH 2/3] Odstranit app.js --- app.js | 226 --------------------------------------------------------- 1 file changed, 226 deletions(-) delete mode 100644 app.js diff --git a/app.js b/app.js deleted file mode 100644 index b04e1e3..0000000 --- a/app.js +++ /dev/null @@ -1,226 +0,0 @@ -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}`); -}); \ No newline at end of file From fffd0e14e8c4356dad9cfc660d0bd76d2f4a53d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Ut=C4=BE=C3=A1k?= Date: Sun, 22 Mar 2026 11:44:52 +0000 Subject: [PATCH 3/3] Odstranit Dockerfile --- Dockerfile | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index d76d490..0000000 --- a/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM node:20-alpine - -WORKDIR /app - -COPY package*.json ./ -RUN npm install - -COPY backend ./backend - -EXPOSE 3000 - -CMD ["node", "backend/app.js"] \ No newline at end of file