From 731c682d65d42ac17eda427afbfb815b975e0318 Mon Sep 17 00:00:00 2001 From: PENN JR Date: Thu, 23 Nov 2023 12:29:29 +0100 Subject: [PATCH 1/4] Working on user registration and login --- data/{posts.json => tasks.json} | 0 data/users.json | 1 + helpers/helper.js | 37 ++---------- helpers/middlewares.js | 34 ++++++----- index.js | 28 ++++++---- models/task.model.js | 53 ++++++++++++++++++ models/user.model.js | 19 +++++++ package-lock.json | 56 ------------------- package.json | 1 - routes/index.routes.js | 38 +++++++++++++ routes/post.routes.js | 0 models/post.model.js => routes/task.routes.js | 0 12 files changed, 151 insertions(+), 116 deletions(-) rename data/{posts.json => tasks.json} (100%) create mode 100644 data/users.json create mode 100644 models/task.model.js create mode 100644 models/user.model.js delete mode 100644 routes/post.routes.js rename models/post.model.js => routes/task.routes.js (100%) diff --git a/data/posts.json b/data/tasks.json similarity index 100% rename from data/posts.json rename to data/tasks.json diff --git a/data/users.json b/data/users.json new file mode 100644 index 0000000..a070cc3 --- /dev/null +++ b/data/users.json @@ -0,0 +1 @@ +[{"id":"1","username":"user1","password":"password1"},{"id":"2","username":"user2","password":"password2"},{"id":"_zwsde6n","username":"james","password":"pass"},{"id":"_xjslaun","username":"bobby","password":"pass"}] \ No newline at end of file diff --git a/helpers/helper.js b/helpers/helper.js index 76e53c8..3fb9d50 100644 --- a/helpers/helper.js +++ b/helpers/helper.js @@ -1,34 +1,7 @@ -const fs = require('fs') -const getNewId = (array) => { - if (array.length > 0) { - return array[array.length - 1].id + 1 - } else { - return 1 - } -} -const newDate = () => new Date().toString() -function mustBeInArray(array, id) { - return new Promise((resolve, reject) => { - const row = array.find(r => r.id == id) - if (!row) { - reject({ - message: 'ID is not good', - status: 404 - }) - } - resolve(row) - }) -} -function writeJSONFile(filename, content) { - fs.writeFileSync(filename, JSON.stringify(content), 'utf8', (err) => { - if (err) { - console.log(err) - } - }) +function generateId() { + return '_' + Math.random().toString(36).substring(2, 9); } + module.exports = { - getNewId, - newDate, - mustBeInArray, - writeJSONFile -} \ No newline at end of file + generateId, +}; \ No newline at end of file diff --git a/helpers/middlewares.js b/helpers/middlewares.js index 16f95d0..5062dda 100644 --- a/helpers/middlewares.js +++ b/helpers/middlewares.js @@ -1,20 +1,24 @@ -function mustBeInteger(req, res, next) { - const id = req.params.id - if (!Number.isInteger(parseInt(id))) { - res.status(400).json({ message: 'ID must be an integer' }) - } else { - next() +let loggedInUser = null; + +function authenticate(username, password) { + // Simulating basic authentication + const user = usersData.find(user => user.username === username && user.password === password); + if (user) { + loggedInUser = user; + return true; } + return false; } -function checkFieldsPost(req, res, next) { - const { title, content, tags } = req.body - if (title && content && tags) { - next() - } else { - res.status(400).json({ message: 'fields are not good' }) + +function requireAuth(req, res, next) { + if (!loggedInUser) { + return res.status(401).send('Unauthorized'); } + req.user = loggedInUser; + next(); } + module.exports = { - mustBeInteger, - checkFieldsPost -} \ No newline at end of file + authenticate, + requireAuth, +}; diff --git a/index.js b/index.js index adbb14c..c4088cf 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,16 @@ -const express = require('express') -const morgan = require('morgan') -// App -const app = express() -// Morgan -app.use(morgan('tiny')) -// First route -app.get('/', (req, res) => { - res.json({ message: 'Hello world' }) -}) -// Starting server -app.listen('2000') \ No newline at end of file + +const express = require('express'); +const app = express(); +const indexRoutes = require('./routes/index.routes'); +// const taskRoutes = require('./routes/task.routes'); + +app.use(express.json()); + +// Routes setup +app.use('/', indexRoutes); +// app.use('/tasks', taskRoutes); + +const PORT = process.env.PORT || 3000; +app.listen(PORT, () => { + console.log(`Server is running on port ${PORT}`); +}); diff --git a/models/task.model.js b/models/task.model.js new file mode 100644 index 0000000..e6549d2 --- /dev/null +++ b/models/task.model.js @@ -0,0 +1,53 @@ +const { generateId } = require('../helpers/helper'); + +class Task { + constructor(userId, title, description, dueDate) { + this.id = generateId(); + this.userId = userId; + this.title = title; + this.description = description; + this.dueDate = dueDate; + this.status = 'pending'; + } + + static getAllTasks(tasksData, userId) { + return tasksData.filter(task => task.userId === userId); + } + + static getTaskById(taskId, tasksData, userId) { + return tasksData.find(task => task.id === taskId && task.userId === userId); + } + + static createTask(newTask, tasksData) { + tasksData.push(newTask); + } + + static updateTaskById(taskId, updatedTask, tasksData, userId) { + const index = tasksData.findIndex(task => task.id === taskId && task.userId === userId); + if (index !== -1) { + tasksData[index] = { ...tasksData[index], ...updatedTask }; + return tasksData[index]; + } + return null; + } + + static deleteTaskById(taskId, tasksData, userId) { + const index = tasksData.findIndex(task => task.id === taskId && task.userId === userId); + if (index !== -1) { + const deletedTask = tasksData.splice(index, 1); + return deletedTask[0]; + } + return null; + } + + static updateTaskStatus(taskId, status, tasksData, userId) { + const task = tasksData.find(task => task.id === taskId && task.userId === userId); + if (task) { + task.status = status; + return task; + } + return null; + } +} + +module.exports = Task; diff --git a/models/user.model.js b/models/user.model.js new file mode 100644 index 0000000..46ffb76 --- /dev/null +++ b/models/user.model.js @@ -0,0 +1,19 @@ +const { generateId } = require('../helpers/helper'); + +class User { + constructor(username, password) { + this.id = generateId(); + this.username = username; + this.password = password; + } + + static createUser(newUser, usersData) { + usersData.push(newUser); + } + + static getUserByUsername(username, usersData) { + return usersData.find(user => user.username === username); + } +} + +module.exports = User; diff --git a/package-lock.json b/package-lock.json index ed510a1..af099cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,6 @@ "express": "^4.18.2" }, "devDependencies": { - "morgan": "^1.10.0", "nodemon": "^3.0.1" } }, @@ -58,24 +57,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -640,34 +621,6 @@ "node": "*" } }, - "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "dev": true, - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -767,15 +720,6 @@ "node": ">= 0.8" } }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", diff --git a/package.json b/package.json index c562222..f1079de 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "express": "^4.18.2" }, "devDependencies": { - "morgan": "^1.10.0", "nodemon": "^3.0.1" } } diff --git a/routes/index.routes.js b/routes/index.routes.js index e69de29..2bb7ece 100644 --- a/routes/index.routes.js +++ b/routes/index.routes.js @@ -0,0 +1,38 @@ +const express = require('express'); +const fs = require('fs'); +const router = express.Router(); +const { authenticate } = require('../helpers/middlewares'); +const User = require('../models/user.model'); +const usersData = require('../data/users.json'); + +// Simulated login route +router.post('/login', (req, res) => { + const { username, password } = req.body; + const isAuthenticated = authenticate(username, password); + if (isAuthenticated) { + res.send('Logged in successfully'); + } else { + res.status(401).send('Authentication failed'); + } +}); + +// Signup route for user registration +router.post('/signup', (req, res) => { + const { username, password } = req.body; + const existingUser = User.getUserByUsername(username, usersData); + if (existingUser) { + return res.status(400).send('Username already exists'); + } + const newUser = new User(username, password); + User.createUser(newUser, usersData); + + // Save updated usersData back to users.json + fs.writeFile('./data/users.json', JSON.stringify(usersData), err => { + if (err) { + return res.status(500).send('Error saving user data'); + } + res.send('User registered successfully'); + }); +}); + +module.exports = router; diff --git a/routes/post.routes.js b/routes/post.routes.js deleted file mode 100644 index e69de29..0000000 diff --git a/models/post.model.js b/routes/task.routes.js similarity index 100% rename from models/post.model.js rename to routes/task.routes.js From fbf3e7e28c2fc307bfba98382cc9e28979049d36 Mon Sep 17 00:00:00 2001 From: PENN JR Date: Fri, 24 Nov 2023 16:39:49 +0100 Subject: [PATCH 2/4] Working on create task, get task, delete task, update task and update task status --- data/tasks.json | 18 ++++++++ data/users.json | 28 +++++++++++- helpers/middlewares.js | 5 ++- index.js | 9 ++-- models/task.model.js | 98 +++++++++++++++++++++++++----------------- models/user.model.js | 39 +++++++++++------ routes/index.routes.js | 15 ++----- routes/task.routes.js | 52 ++++++++++++++++++++++ 8 files changed, 196 insertions(+), 68 deletions(-) diff --git a/data/tasks.json b/data/tasks.json index e69de29..b3f3525 100644 --- a/data/tasks.json +++ b/data/tasks.json @@ -0,0 +1,18 @@ +[ + { + "id": "_uaszbz8", + "userId": "_xjslaun", + "title": "Testing", + "description": "works", + "dueDate": "2023-12-03", + "status": "pending" + }, + { + "id": "_ziyuo0z", + "userId": "_islqrzy", + "title": "MackPro 2023", + "description": "Will work had to get one some day", + "dueDate": "2023-11-24", + "status": "completed" + } +] \ No newline at end of file diff --git a/data/users.json b/data/users.json index a070cc3..b1e49f7 100644 --- a/data/users.json +++ b/data/users.json @@ -1 +1,27 @@ -[{"id":"1","username":"user1","password":"password1"},{"id":"2","username":"user2","password":"password2"},{"id":"_zwsde6n","username":"james","password":"pass"},{"id":"_xjslaun","username":"bobby","password":"pass"}] \ No newline at end of file +[ + { + "id": "1", + "username": "user1", + "password": "password1" + }, + { + "id": "2", + "username": "user2", + "password": "password2" + }, + { + "id": "_zwsde6n", + "username": "james", + "password": "pass" + }, + { + "id": "_xjslaun", + "username": "bobby", + "password": "pass" + }, + { + "id": "_islqrzy", + "username": "macbook", + "password": "oneday" + } +] \ No newline at end of file diff --git a/helpers/middlewares.js b/helpers/middlewares.js index 5062dda..03a48b4 100644 --- a/helpers/middlewares.js +++ b/helpers/middlewares.js @@ -1,8 +1,11 @@ +const usersData = require('../data/users.json'); let loggedInUser = null; function authenticate(username, password) { // Simulating basic authentication - const user = usersData.find(user => user.username === username && user.password === password); + const user = usersData.find( + user => user.username === username && user.password === password + ); if (user) { loggedInUser = user; return true; diff --git a/index.js b/index.js index c4088cf..7f62128 100644 --- a/index.js +++ b/index.js @@ -2,13 +2,16 @@ const express = require('express'); const app = express(); const indexRoutes = require('./routes/index.routes'); -// const taskRoutes = require('./routes/task.routes'); +const taskRoutes = require('./routes/task.routes'); app.use(express.json()); - +app.use((req, res, next) => { + console.log(`Request: ${req.method} ${req.url}`); + next(); +}); // Routes setup app.use('/', indexRoutes); -// app.use('/tasks', taskRoutes); +app.use('/tasks', taskRoutes); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { diff --git a/models/task.model.js b/models/task.model.js index e6549d2..cff12d2 100644 --- a/models/task.model.js +++ b/models/task.model.js @@ -1,53 +1,73 @@ +const fs = require('fs'); const { generateId } = require('../helpers/helper'); -class Task { - constructor(userId, title, description, dueDate) { - this.id = generateId(); - this.userId = userId; - this.title = title; - this.description = description; - this.dueDate = dueDate; - this.status = 'pending'; - } +function getAllTasks(tasksData, userId) { + return tasksData.filter(task => task.userId === userId); +} - static getAllTasks(tasksData, userId) { - return tasksData.filter(task => task.userId === userId); - } +function getTaskById(taskId, tasksData, userId) { + return tasksData.find(task => task.id === taskId && task.userId === userId); +} - static getTaskById(taskId, tasksData, userId) { - return tasksData.find(task => task.id === taskId && task.userId === userId); - } +function createTask(userId, title, description, dueDate, tasksData) { + const newTask = { + id: generateId(), + userId, + title, + description, + dueDate, + status: 'pending', + }; + tasksData.push(newTask); + saveTasksToFile(tasksData); + return newTask; +} - static createTask(newTask, tasksData) { - tasksData.push(newTask); +function updateTaskById(taskId, updatedTask, tasksData, userId) { + const index = tasksData.findIndex(task => task.id === taskId && task.userId === userId); + if (index !== -1) { + tasksData[index] = { ...tasksData[index], ...updatedTask }; + saveTasksToFile(tasksData); + return tasksData[index]; } + return null; +} - static updateTaskById(taskId, updatedTask, tasksData, userId) { - const index = tasksData.findIndex(task => task.id === taskId && task.userId === userId); - if (index !== -1) { - tasksData[index] = { ...tasksData[index], ...updatedTask }; - return tasksData[index]; - } - return null; +function deleteTaskById(taskId, tasksData, userId) { + const index = tasksData.findIndex(task => task.id === taskId && task.userId === userId); + if (index !== -1) { + const deletedTask = tasksData.splice(index, 1); + saveTasksToFile(tasksData); + return deletedTask[0]; } + return null; +} - static deleteTaskById(taskId, tasksData, userId) { - const index = tasksData.findIndex(task => task.id === taskId && task.userId === userId); - if (index !== -1) { - const deletedTask = tasksData.splice(index, 1); - return deletedTask[0]; - } - return null; +function updateTaskStatus(taskId, status, tasksData, userId) { + const task = tasksData.find(task => task.id === taskId && task.userId === userId); + if (task) { + task.status = status; + saveTasksToFile(tasksData); + return task; } + return null; +} - static updateTaskStatus(taskId, status, tasksData, userId) { - const task = tasksData.find(task => task.id === taskId && task.userId === userId); - if (task) { - task.status = status; - return task; +function saveTasksToFile(tasksData) { + fs.writeFile('data/tasks.json', JSON.stringify(tasksData, null, 2), 'utf8', err => { + if (err) { + console.error(err); + return; } - return null; - } + console.log('Tasks saved to file successfully!'); + }); } -module.exports = Task; +module.exports = { + getAllTasks, + getTaskById, + createTask, + updateTaskById, + deleteTaskById, + updateTaskStatus, +}; diff --git a/models/user.model.js b/models/user.model.js index 46ffb76..39d99b5 100644 --- a/models/user.model.js +++ b/models/user.model.js @@ -1,19 +1,32 @@ +const fs = require('fs'); const { generateId } = require('../helpers/helper'); -class User { - constructor(username, password) { - this.id = generateId(); - this.username = username; - this.password = password; - } +function createUser(username, password, usersData) { + const newUser = { + id: generateId(), + username, + password, + }; + usersData.push(newUser); + return newUser; // Return the new user without saving to file here +} - static createUser(newUser, usersData) { - usersData.push(newUser); - } +function getUserByUsername(username, usersData) { + return usersData.find(user => user.username === username); +} - static getUserByUsername(username, usersData) { - return usersData.find(user => user.username === username); - } +function saveUsersToFile(usersData) { + fs.writeFile('data/users.json', JSON.stringify(usersData, null, 2), 'utf8', err => { + if (err) { + console.error(err); + return; + } + console.log('Users saved to file successfully!'); + }); } -module.exports = User; +module.exports = { + createUser, + getUserByUsername, + saveUsersToFile, +}; diff --git a/routes/index.routes.js b/routes/index.routes.js index 2bb7ece..e1dd568 100644 --- a/routes/index.routes.js +++ b/routes/index.routes.js @@ -1,11 +1,9 @@ const express = require('express'); -const fs = require('fs'); const router = express.Router(); const { authenticate } = require('../helpers/middlewares'); const User = require('../models/user.model'); const usersData = require('../data/users.json'); -// Simulated login route router.post('/login', (req, res) => { const { username, password } = req.body; const isAuthenticated = authenticate(username, password); @@ -16,23 +14,18 @@ router.post('/login', (req, res) => { } }); -// Signup route for user registration router.post('/signup', (req, res) => { const { username, password } = req.body; const existingUser = User.getUserByUsername(username, usersData); if (existingUser) { return res.status(400).send('Username already exists'); } - const newUser = new User(username, password); - User.createUser(newUser, usersData); + const newUser = User.createUser(username, password, usersData); // Save updated usersData back to users.json - fs.writeFile('./data/users.json', JSON.stringify(usersData), err => { - if (err) { - return res.status(500).send('Error saving user data'); - } - res.send('User registered successfully'); - }); + User.saveUsersToFile(usersData); + + res.send('User registered successfully'); }); module.exports = router; diff --git a/routes/task.routes.js b/routes/task.routes.js index e69de29..3609855 100644 --- a/routes/task.routes.js +++ b/routes/task.routes.js @@ -0,0 +1,52 @@ +const express = require('express'); +const router = express.Router(); +const Task = require('../models/task.model'); +const tasksData = require('../data/tasks.json'); +const { requireAuth } = require('../helpers/middlewares'); + +router.use(requireAuth); + +router.get('/', (req, res) => { + const userTasks = Task.getAllTasks(tasksData, req.user.id); + res.json(userTasks); +}); + +router.post('/', (req, res) => { + const { title, description, dueDate } = req.body; + const newTask = Task.createTask(req.user.id, title, description, dueDate, tasksData); + res.json(newTask); +}); + +router.put('/:id', (req, res) => { + const taskId = req.params.id; + const updatedTask = req.body; + const result = Task.updateTaskById(taskId, updatedTask, tasksData, req.user.id); + if (result) { + res.json(result); + } else { + res.status(404).send('Task not found'); + } +}); + +router.delete('/:id', (req, res) => { + const taskId = req.params.id; + const deletedTask = Task.deleteTaskById(taskId, tasksData, req.user.id); + if (deletedTask) { + res.json(deletedTask); + } else { + res.status(404).send('Task not found'); + } +}); + +router.patch('/:id/status', (req, res) => { + const taskId = req.params.id; + const { status } = req.body; + const updatedTask = Task.updateTaskStatus(taskId, status, tasksData, req.user.id); + if (updatedTask) { + res.json(updatedTask); + } else { + res.status(404).send('Task not found'); + } +}); + +module.exports = router; From 989fc7fea9b65130a21abb55b2ca2735b3dda894 Mon Sep 17 00:00:00 2001 From: PENN JR Date: Sat, 25 Nov 2023 17:54:15 +0100 Subject: [PATCH 3/4] Working on index route --- routes/index.routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/index.routes.js b/routes/index.routes.js index e1dd568..31b12dd 100644 --- a/routes/index.routes.js +++ b/routes/index.routes.js @@ -22,7 +22,7 @@ router.post('/signup', (req, res) => { } const newUser = User.createUser(username, password, usersData); - // Save updated usersData back to users.json + // Save usersData back to users.json User.saveUsersToFile(usersData); res.send('User registered successfully'); From 07f165a9f670ad3019480c2dd0cbfd64a8551f1f Mon Sep 17 00:00:00 2001 From: PENN JR Date: Wed, 29 Nov 2023 18:19:16 +0100 Subject: [PATCH 4/4] Changes --- routes/index.routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/index.routes.js b/routes/index.routes.js index 31b12dd..fa3df3d 100644 --- a/routes/index.routes.js +++ b/routes/index.routes.js @@ -22,7 +22,7 @@ router.post('/signup', (req, res) => { } const newUser = User.createUser(username, password, usersData); - // Save usersData back to users.json + // Save your usersData back to users.json User.saveUsersToFile(usersData); res.send('User registered successfully');