Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 127 additions & 2 deletions app/server.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');
const swaggerDocument = YAML.load('./swagger.yaml'); // Replace './swagger.yaml' with the path to your Swagger file
const app = express();
require('dotenv').config();

app.use(bodyParser.json());
app.use(express.json());

// Importing the data from JSON files
const users = require('../initial-data/users.json');
Expand All @@ -22,6 +22,131 @@ app.use((err, req, res, next) => {
// Swagger
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

// Authenticate token when login is required
const authenticate = (req, res, next) => {
try {
const token = req.headers['authorization']; // Get token from Authorization header
if (!token) {
return res.status(401).json({ message: 'No token provided' })
}
const decoded = jwt.verify(token, process.env.JWT_SECRET) // Access info from token using decoded
const user = users.find((u) => u.login.username === decoded.username) // Locate user info
if (!user) {
return res.status(404).json({ message: 'User not found' });
}

req.user = user

next();
}
catch (error) { // Use built in error names for errors with token
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({ message: 'Invalid token' });
} else if (error.name === 'TokenExpiredError') {
return res.status(401).json({ message: 'Token has expired' });
}
res.status(401).json({ message: 'Authentication failed'})
}
}

// Route to get brands
app.get('/brands', (req, res) => {
res.status(200).json(brands);
});

// Route to get products by selected brand
app.get('/products', (req, res) => {
const brandId = parseInt(req.query.brandId) // Get brandId from query

if(!brandId) {
return res.status(400).json({ message: 'Brand ID is required'})
}

const brandProducts = products.filter(product => product.categoryId === brandId) // Set brandId to the categoryId for each product listed

if (brandProducts.length === 0) {
return res.status(404).json({ message: 'No products for this brand found'})
}

res.status(200).json(brandProducts)
})


// Route to authenticate users and generate JWT token
app.post('/login', (req, res) => {
const { username, password } = req.body; //pull username and password from request
const user = users.find(u => u.login.username === username); //searching for user with username which match request

if (!user || user.login.password !== password) { // if password or username don't match or don't exist, give error 401
return res.status(401).json({ message: 'Invalid credentials' });
}

// Generate a JWT token with user data
const token = jwt.sign(
{ username: user.login.username },
process.env.JWT_SECRET, // Using a secret key from environment variables
{ expiresIn: '1h' }
);

res.set('authorization', token);

return res.status(200).json({ token: token }); // Response to be returned
});


// Route to authenticate token and get cart
app.get('/cart', authenticate, (req, res) => {
const user = req.user
res.status(200).json(user.cart); // Send the cart items in the response
})

// Route to add an item to user's cart
app.post('/cart', authenticate, (req, res) => {
const user = req.user
const { newItem } = req.body

try {
if (!user.cart) {
user.cart = [];
}

const existingItem = user.cart.find((item) => item.id === newItem.id);

if (existingItem) {
existingItem.quantity += newItem.quantity
}

else {
user.cart.push({
id: newItem.id,
quantity: newItem.quantity,
name: newItem.name,
description: newItem.description,
price: newItem.price
});
}

res.status(200).json({ message: 'Item added to cart', cart: user.cart });
} catch (error) {
console.error(error);
res.status(500).json({ message: error.message });
}
})

app.delete('/cart:itemId', authenticate, (req, res) => {
const user = req.user
const { itemId } = req.params;
const itemIndex = user.cart.findIndex((item) => item.id === parseInt(itemId))

if (itemIndex === -1) {
return res.status(404).json({ message: 'Item not found in cart'})
}

user.cart.splice(itemIndex, 1)
res.status(200).json({message: 'Item removed from cart', cart: user.cart})
})


// Starting the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
Expand Down
22 changes: 22 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import globals from "globals";
import pluginJs from "@eslint/js";


/** @type {import('eslint').Linter.Config[]} */
export default [
{files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
// {
// "env": {
// "node": true,
// "es2021": true
// },
// "parserOptions": {
// "ecmaVersion": 2021
// },
// "rules": {
// "no-undef": "error"
// }
// }
];
222 changes: 133 additions & 89 deletions initial-data/products.json
Original file line number Diff line number Diff line change
@@ -1,90 +1,134 @@
[
{
"id": "1",
"categoryId": "1",
"name": "Superglasses",
"description": "The best glasses in the world",
"price":150,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "2",
"categoryId": "1",
"name": "Black Sunglasses",
"description": "The best glasses in the world",
"price":100,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "3",
"categoryId": "1",
"name": "Brown Sunglasses",
"description": "The best glasses in the world",
"price":50,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "4",
"categoryId": "2",
"name": "Better glasses",
"description": "The best glasses in the world",
"price":1500,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "5",
"categoryId": "2",
"name": "Glasses",
"description": "The most normal glasses in the world",
"price":150,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "6",
"categoryId": "3",
"name": "glas",
"description": "Pretty awful glasses",
"price":10,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "7",
"categoryId": "3",
"name": "QDogs Glasses",
"description": "They bark",
"price":1500,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "8",
"categoryId": "4",
"name": "Coke cans",
"description": "The thickest glasses in the world",
"price":110,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "9",
"categoryId": "4",
"name": "Sugar",
"description": "The sweetest glasses in the world",
"price":125,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "10",
"categoryId": "5",
"name": "Peanut Butter",
"description": "The stickiest glasses in the world",
"price":103,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
},
{
"id": "11",
"categoryId": "5",
"name": "Habanero",
"description": "The spiciest glasses in the world",
"price":153,
"imageUrls":["https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg","https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"]
}
]
{
"id": 1,
"categoryId": 1,
"name": "Superglasses",
"description": "The best glasses in the world",
"price": 150,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 2,
"categoryId": 1,
"name": "Black Sunglasses",
"description": "The best glasses in the world",
"price": 100,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 3,
"categoryId": 1,
"name": "Brown Sunglasses",
"description": "The best glasses in the world",
"price": 50,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 4,
"categoryId": 2,
"name": "Better glasses",
"description": "The best glasses in the world",
"price": 1500,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 5,
"categoryId": 2,
"name": "Glasses",
"description": "The most normal glasses in the world",
"price": 150,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 6,
"categoryId": 3,
"name": "glas",
"description": "Pretty awful glasses",
"price": 10,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 7,
"categoryId": 3,
"name": "QDogs Glasses",
"description": "They bark",
"price": 1500,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 8,
"categoryId": 4,
"name": "Coke cans",
"description": "The thickest glasses in the world",
"price": 110,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 9,
"categoryId": 4,
"name": "Sugar",
"description": "The sweetest glasses in the world",
"price": 125,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 10,
"categoryId": 5,
"name": "Peanut Butter",
"description": "The stickiest glasses in the world",
"price": 103,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
},
{
"id": 11,
"categoryId": 5,
"name": "Habanero",
"description": "The spiciest glasses in the world",
"price": 153,
"imageUrls": [
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg",
"https://image.shutterstock.com/z/stock-photo-yellow-sunglasses-white-backgound-600820286.jpg"
]
}
]
Loading