From 84c5d260f26a2d26464ebadb0d33991723d74948 Mon Sep 17 00:00:00 2001 From: cs15l Date: Thu, 25 May 2023 08:39:12 -0700 Subject: [PATCH 1/4] migrations --- backend/app/models/user_model.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/app/models/user_model.js b/backend/app/models/user_model.js index 42463eb..0c1a552 100644 --- a/backend/app/models/user_model.js +++ b/backend/app/models/user_model.js @@ -16,7 +16,8 @@ module.exports = (sequelize, Sequelize) => { passwordHash: { type: Sequelize.DataTypes.STRING, allowNull: false - } + }, + }); return User; From 8bd987e36affed29042737790b65b913e36c34ee Mon Sep 17 00:00:00 2001 From: cs15l Date: Thu, 25 May 2023 08:39:58 -0700 Subject: [PATCH 2/4] migrations again --- backend/app/models/favorites_model.js | 16 ++++++++ backend/migrations/0002-AddFavoritesTable.js | 39 ++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 backend/app/models/favorites_model.js create mode 100644 backend/migrations/0002-AddFavoritesTable.js diff --git a/backend/app/models/favorites_model.js b/backend/app/models/favorites_model.js new file mode 100644 index 0000000..f97df5c --- /dev/null +++ b/backend/app/models/favorites_model.js @@ -0,0 +1,16 @@ +module.exports = (sequelize, Sequelize) => { + const Favorite = sequelize.define('Favorite', { + id: { + primaryKey: true, + type: Sequelize.DataTypes.UUID, + defaultValue: Sequelize.DataTypes.UUIDV4 + }, + user: { + type: Sequelize.DataTypes.UUID + }, + favorite: { + type: Sequelize.DataTypes.UUID + } + + }); +} \ No newline at end of file diff --git a/backend/migrations/0002-AddFavoritesTable.js b/backend/migrations/0002-AddFavoritesTable.js new file mode 100644 index 0000000..ecfc68b --- /dev/null +++ b/backend/migrations/0002-AddFavoritesTable.js @@ -0,0 +1,39 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up (queryInterface, Sequelize) { + /** + * Add altering commands here. + * + * Example: + * await queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + await queryInterface.createTable('Favorites', { + id: { + primaryKey: true, + type: Sequelize.DataTypes.UUID, + defaultValue: Sequelize.DataTypes.UUIDV4, + allowNull: false + }, + user: { + type: Sequelize.DataTypes.UUID, + allowNull: false + }, + favorite: { + type: Sequelize.DataTypes.UUID, + allowNull: false + } + }); + }, + + async down (queryInterface, Sequelize) { + /** + * Add reverting commands here. + * + * Example: + * await queryInterface.dropTable('users'); + */ + await queryInterface.dropTable('Favorites'); + } +}; From c69a7d7ff847829570c80f74c9cef769b9c44da9 Mon Sep 17 00:00:00 2001 From: cs15l Date: Mon, 5 Jun 2023 00:47:56 -0700 Subject: [PATCH 3/4] add remove favorite routes --- backend/app/models/user_model.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/models/user_model.js b/backend/app/models/user_model.js index 0c1a552..dcb1f98 100644 --- a/backend/app/models/user_model.js +++ b/backend/app/models/user_model.js @@ -16,7 +16,7 @@ module.exports = (sequelize, Sequelize) => { passwordHash: { type: Sequelize.DataTypes.STRING, allowNull: false - }, + } }); From 571602e5437091277fb910094635cca749ae8917 Mon Sep 17 00:00:00 2001 From: cs15l Date: Mon, 5 Jun 2023 00:48:55 -0700 Subject: [PATCH 4/4] remove add favorite route --- .../app/controllers/favorites_controllers.js | 83 +++++++++++++++++++ backend/app/middleware/authentication.js | 23 +++++ backend/app/routes/favorites_route.js | 8 ++ backend/app/services/favorites_services.js | 0 4 files changed, 114 insertions(+) create mode 100644 backend/app/controllers/favorites_controllers.js create mode 100644 backend/app/middleware/authentication.js create mode 100644 backend/app/routes/favorites_route.js create mode 100644 backend/app/services/favorites_services.js diff --git a/backend/app/controllers/favorites_controllers.js b/backend/app/controllers/favorites_controllers.js new file mode 100644 index 0000000..71f23a2 --- /dev/null +++ b/backend/app/controllers/favorites_controllers.js @@ -0,0 +1,83 @@ +const { Favorite } = require('./models'); +const { User } = require('./models'); + +module.exports = { + addFavorite(req, res) { + const { username } = req.body; + const { userId } = req.user; + + // Validate both user IDs exist + try { + User.findOne({ where: { username } }) + .then(user => { + if (!user || !userId) { + return res.status(400).json({ error: 'Invalid user ID' }); + } + + // Check if an entry in the Favorites table already exists + Favorite.findOne({ where: { user: userId, favorite: username } }) + .then(existingFavorite => { + if (existingFavorite) { + return res.status(400).json({ error: 'Favorite already exists' }); + } + + // Create a Favorites entry with user as the userId from the JWT, and the favorite as the request body + Favorite.create({ user: userId, favorite: username }) + .then(() => { + // Return a 200 OK response + res.status(200).json({ message: 'Favorite created successfully' }); + }) + .catch(error => { + console.error(error); + res.status(500).json({ error: 'Internal Server Error' }); + }); + }) + .catch(error => { + console.error(error); + res.status(500).json({ error: 'Internal Server Error' }); + }); + }) + .catch(error => { + console.error(error); + res.status(500).json({ error: 'Internal Server Error' }); + }); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Internal Server Error' }); + } + }, + + removeFavorite(req, res) { + const { username } = req.body; + const { userId } = req.user; + + // Validate both user IDs exist + try { + Favorite.findOne({ where: { user: userId, favorite: username } }) + .then(favorite => { + if (!favorite) { + return res.status(400).json({ error: 'Favorite does not exist' }); + } + + // Remove the entry from the database + favorite.destroy() + .then(() => { + // Return a 200 OK response + res.status(200).json({ message: 'Favorite removed successfully' }); + }) + .catch(error => { + console.error(error); + res.status(500).json({ error: 'Internal Server Error' }); + }); + }) + .catch(error => { + console.error(error); + res.status(500).json({ error: 'Internal Server Error' }); + }); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Internal Server Error' }); + } + } + +} \ No newline at end of file diff --git a/backend/app/middleware/authentication.js b/backend/app/middleware/authentication.js new file mode 100644 index 0000000..20107f1 --- /dev/null +++ b/backend/app/middleware/authentication.js @@ -0,0 +1,23 @@ +const jwt = require('jsonwebtoken'); + +function authenticateToken(res,req,next) { + const authHeader = req.headers['authorization']; + const token = authHeader && authHeader.split(' ')[1]; + + if(!token) { + return res.sendStatus(401); // Unauthorized + } + + jwt.verify(token, 'YOUR_SECRET_KEY', (err, user) => { + if (err) { + return res.sendStatus(401); // Unauthorized + } + req.user = user; + next(); + }); + } + + module.exports = { + authenticateToken + +}; \ No newline at end of file diff --git a/backend/app/routes/favorites_route.js b/backend/app/routes/favorites_route.js new file mode 100644 index 0000000..94e685f --- /dev/null +++ b/backend/app/routes/favorites_route.js @@ -0,0 +1,8 @@ +const express = require('express'); +const router = express.Router(); +const { addFavorite, removeFavorite } = require('../controllers/favorites_controllers.js'); + +router.post('/',addFavorite); +router.delete('/',removeFavorite); + +module.exports = router; diff --git a/backend/app/services/favorites_services.js b/backend/app/services/favorites_services.js new file mode 100644 index 0000000..e69de29