diff --git a/public/index.html b/public/index.html index 7b7508e..b83a121 100644 --- a/public/index.html +++ b/public/index.html @@ -56,7 +56,7 @@
- +
diff --git a/public/js/tags.js b/public/js/tags.js index 8803b89..5e61004 100644 --- a/public/js/tags.js +++ b/public/js/tags.js @@ -1,10 +1,13 @@ -export function saveTags(tags) { +export async function saveTags(newTags) { + const existingTags = await loadTags(); + const allTags = Array.from(new Set([...existingTags, ...newTags])); + return fetch('/save-tags', { method: 'POST', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ tags }) + body: JSON.stringify({ tags: allTags }) }); } diff --git a/routes/tasks.js b/routes/tasks.js index 742c93b..fdffb7d 100644 --- a/routes/tasks.js +++ b/routes/tasks.js @@ -3,10 +3,17 @@ const fs = require('fs'); const path = require('path'); const auth = require('../middleware/auth'); const logger = require('../logger'); +const sqlite3 = require('sqlite3').verbose(); const router = express.Router(); const dataDir = '/data'; +const db = new sqlite3.Database('/data/sessions.sqlite', (err) => { + if (err) { + console.error('Error opening database:', err); + } +}); + // Ensure the /data directory exists if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir, { recursive: true }); @@ -68,28 +75,31 @@ router.post('/add-task', auth, async (req, res) => { // Endpoint to save tags router.post('/save-tags', auth, async (req, res) => { const { tags } = req.body; - const filePath = path.join(dataDir, 'tags.json'); - try { - await fs.promises.writeFile(filePath, JSON.stringify(tags)); - res.send({ message: 'Tags saved successfully!' }); - logger.info(`New tags saved: ${tags}`); - } catch (err) { - logger.error('Error saving tags:', err); - res.status(500).send('Error saving tags.'); - } + const placeholders = tags.map(() => '(?)').join(','); + const sql = `INSERT OR IGNORE INTO tags (tag) VALUES ${placeholders}`; + + db.run(sql, tags, function(err) { + if (err) { + logger.error('Error saving tags:', err); + res.status(500).send('Error saving tags.'); + } else { + res.send({ message: 'Tags saved successfully!' }); + logger.info(`New tags saved: ${tags}`); + } + }); }); // Endpoint to retrieve tags router.get('/get-tags', auth, async (req, res) => { - const filePath = path.join(dataDir, 'tags.json'); - try { - const data = await fs.promises.readFile(filePath, 'utf-8'); - const tags = JSON.parse(data); - res.json(tags); - } catch (err) { - logger.error('Error retrieving tags:', err); - res.status(500).json({ error: 'Error retrieving tags' }); - } + db.all('SELECT tag FROM tags', [], (err, rows) => { + if (err) { + logger.error('Error retrieving tags:', err); + res.status(500).json({ error: 'Error retrieving tags' }); + } else { + const tags = rows.map(row => row.tag); + res.json(tags); + } + }); }); module.exports = router; \ No newline at end of file diff --git a/server.js b/server.js index 10f791c..c34c3de 100644 --- a/server.js +++ b/server.js @@ -4,6 +4,7 @@ const bodyParser = require('body-parser'); const session = require('express-session'); const cookieParser = require('cookie-parser'); const SQLiteStore = require('connect-sqlite3')(session); +const sqlite3 = require('sqlite3').verbose(); const tasksRouter = require('./routes/tasks'); const authRouter = require('./routes/auth'); const authMiddleware = require('./middleware/auth'); @@ -12,6 +13,21 @@ const logger = require('./logger'); const app = express(); const port = 3044; +const db = new sqlite3.Database('/data/sessions.sqlite', (err) => { + if (err) { + console.error('Error opening database:', err); + } else { + db.run(`CREATE TABLE IF NOT EXISTS tags ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + tag TEXT UNIQUE + )`, (err) => { + if (err) { + console.error('Error creating tags table:', err); + } + }); + } +}); + app.use(bodyParser.json()); app.use(cookieParser()); app.use(express.static('public')); @@ -27,8 +43,7 @@ app.use(session({ ttl: 30 * 24 * 60 * 60 // 1 month }), cookie: { - //secure: process.env.NODE_ENV === 'production', // Ensure cookies are only sent over HTTPS in production - secure: false, + secure: process.env.NODE_ENV === 'production', // Ensure cookies are only sent over HTTPS in production maxAge: 30 * 24 * 60 * 60 * 1000 // 1 month } })); @@ -36,6 +51,35 @@ app.use(session({ app.use('/', authRouter); app.use('/', authMiddleware, tasksRouter); +// Add routes for handling tags +app.post('/save-tags', authMiddleware, (req, res) => { + const { tags } = req.body; + const placeholders = tags.map(() => '(?)').join(','); + const sql = `INSERT OR IGNORE INTO tags (tag) VALUES ${placeholders}`; + + db.run(sql, tags, function(err) { + if (err) { + logger.error('Error saving tags:', err); + res.status(500).send('Error saving tags.'); + } else { + res.send({ message: 'Tags saved successfully!' }); + logger.info(`New tags saved: ${tags}`); + } + }); +}); + +app.get('/get-tags', authMiddleware, (req, res) => { + db.all('SELECT tag FROM tags', [], (err, rows) => { + if (err) { + logger.error('Error retrieving tags:', err); + res.status(500).json({ error: 'Error retrieving tags' }); + } else { + const tags = rows.map(row => row.tag); + res.json(tags); + } + }); +}); + app.listen(port, () => { logger.info(`Server running at http://localhost:${port}`); });