S50 Capstone added
parent
acfadce5cb
commit
4b003da8da
@ -0,0 +1 @@
|
||||
web: node index.js
|
@ -1,40 +1,53 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
require("dotenv").config()
|
||||
// middlewares/auth.js
|
||||
|
||||
// Function to verify JWT token
|
||||
exports.verifyToken = (token) => {
|
||||
try {
|
||||
const decoded = jwt.verify(token, process.env.SECRET_SAUCE);
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return null; // Return null if verification fails
|
||||
}
|
||||
};
|
||||
const jwt = require("jsonwebtoken")
|
||||
require("dotenv").config()
|
||||
|
||||
// Middleware for verifying JWT token
|
||||
// Middleware for verifying and authenticating JWT token
|
||||
exports.authenticateToken = (req, res, next) => {
|
||||
// Extract the token from the Authorization header
|
||||
const token = req.header('Authorization')?.replace('Bearer ', '');
|
||||
const token = req.header("Authorization")?.replace("Bearer ", "")
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ message: 'Unauthorized. Token not provided.' });
|
||||
return res
|
||||
.status(401)
|
||||
.json({ message: "Unauthorized. Token not provided." })
|
||||
}
|
||||
|
||||
const decoded = exports.verifyToken(token);
|
||||
console.log("Token:", token) // Log the token to the console
|
||||
|
||||
if (!decoded) {
|
||||
return res.status(401).json({ message: 'Unauthorized. Invalid token.' });
|
||||
}
|
||||
try {
|
||||
const decoded = jwt.verify(token, process.env.SECRET_SAUCE)
|
||||
req.user = decoded // Attach the decoded information to the request for future use
|
||||
|
||||
// Attach the decoded information to the request for future use
|
||||
req.user = decoded;
|
||||
// dEBUGGING PURPOSES
|
||||
console.log("userId:", decoded.userId)
|
||||
console.log("isAdmin:", decoded.isAdmin)
|
||||
|
||||
// Proceed to the next middleware or route handler
|
||||
next();
|
||||
};
|
||||
next()
|
||||
} catch (error) {
|
||||
console.error("Token Verification Error:", error)
|
||||
return res
|
||||
.status(401)
|
||||
.json({ message: "Unauthorized. Invalid or expired token." })
|
||||
}
|
||||
}
|
||||
|
||||
// Function to generate a JWT token
|
||||
exports.generateToken = (userId, email) => {
|
||||
return jwt.sign({ userId, email }, process.env.SECRET_SAUCE, { expiresIn: '1h' });
|
||||
};
|
||||
exports.generateToken = (userId, email, isAdmin) => {
|
||||
return jwt.sign({ userId, email, isAdmin }, process.env.SECRET_SAUCE, {
|
||||
expiresIn: "1h",
|
||||
})
|
||||
}
|
||||
|
||||
// Middleware to verify admin status
|
||||
exports.verifyAdmin = (req, res, next) => {
|
||||
if (req.user && req.user.isAdmin) {
|
||||
next()
|
||||
} else {
|
||||
return res
|
||||
.status(403)
|
||||
.json({ message: "Action Forbidden. User is not an admin." })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
const User = require("../model/User")
|
||||
|
||||
exports.createOrder = async (req, res) => {
|
||||
try {
|
||||
const { userId, products, totalAmount } = req.body
|
||||
|
||||
const user = await User.findById(userId)
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ message: "User not found" })
|
||||
}
|
||||
|
||||
const newOrder = {
|
||||
products: products,
|
||||
totalAmount: totalAmount,
|
||||
purchaseOn: Date.now(),
|
||||
}
|
||||
|
||||
user.orderedProducts.push(newOrder)
|
||||
await user.save()
|
||||
|
||||
res.status(201).json({
|
||||
message: "Order created successfully",
|
||||
order: newOrder,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
res.status(500).json({ message: "Internal Server Error" })
|
||||
}
|
||||
}
|
@ -1,52 +1,141 @@
|
||||
// productController.js
|
||||
const Product = require('../model/Product');
|
||||
const Product = require("../model/Product")
|
||||
|
||||
// Controller function for creating a product (accessible only by isAdmin)
|
||||
exports.createProduct = async (req, res) => {
|
||||
try {
|
||||
// Check if the user is an admin
|
||||
if (!req.user.isAdmin) {
|
||||
return res.status(403).json({ message: 'Permission denied. Only admins can create products.' });
|
||||
const { name, description, price } = req.body
|
||||
|
||||
const newProduct = new Product({ name, description, price })
|
||||
await newProduct.save()
|
||||
res.status(201).json(newProduct)
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message })
|
||||
}
|
||||
}
|
||||
|
||||
// Controller function for retrieving all products (accessible to both admin and normal user)
|
||||
exports.getAllProducts = async (req, res) => {
|
||||
try {
|
||||
const products = await Product.find()
|
||||
|
||||
res.status(200).json(products)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
res.status(500).json({ message: "Internal server error" })
|
||||
}
|
||||
}
|
||||
|
||||
// Controller function for retrieving all active products (accessible to both admin and normal user)
|
||||
exports.getActiveProducts = async (req, res) => {
|
||||
try {
|
||||
const activeProducts = await Product.find({ isActive: true })
|
||||
|
||||
res.status(200).json(activeProducts)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
res.status(500).json({ message: "Internal server error" })
|
||||
}
|
||||
}
|
||||
|
||||
// Controller to retrieve a single product by id
|
||||
exports.getProductById = async (req, res) => {
|
||||
const productId = req.params.id;
|
||||
|
||||
try {
|
||||
const product = await Product.findById(productId);
|
||||
|
||||
if (!product) {
|
||||
return res.status(404).json({ message: 'Product not found' });
|
||||
}
|
||||
|
||||
res.status(200).json(product);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Controller function to update product information
|
||||
exports.updateProduct = async (req, res) => {
|
||||
const productId = req.params.id;
|
||||
const { name, description, price, isActive } = req.body;
|
||||
|
||||
const newProduct = new Product({
|
||||
name,
|
||||
description,
|
||||
price,
|
||||
isActive,
|
||||
});
|
||||
try {
|
||||
// Check if the product exists
|
||||
const existingProduct = await Product.findById(productId);
|
||||
if (!existingProduct) {
|
||||
return res.status(404).json({ message: 'Product not found' });
|
||||
}
|
||||
|
||||
// Update product information
|
||||
existingProduct.name = name;
|
||||
existingProduct.description = description;
|
||||
existingProduct.price = price;
|
||||
existingProduct.isActive = isActive;
|
||||
|
||||
await newProduct.save();
|
||||
// Save the updated product
|
||||
const updatedProduct = await existingProduct.save();
|
||||
|
||||
res.status(201).json({ message: 'Product created successfully' });
|
||||
res.status(200).json(updatedProduct);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
res.status(500).json({ message: 'Internal Server Error' });
|
||||
}
|
||||
};
|
||||
|
||||
// Controller function for retrieving all products (accessible to both admin and normal user)
|
||||
exports.getAllProducts = async (req, res) => {
|
||||
exports.activateProduct = async (req, res) => {
|
||||
const { productId } = req.params;
|
||||
|
||||
try {
|
||||
const products = await Product.find();
|
||||
// Find the product by ID
|
||||
const product = await Product.findById(productId);
|
||||
|
||||
if (!product) {
|
||||
return res.status(404).json({ message: 'Product not found' });
|
||||
}
|
||||
|
||||
// Check if the product is already active
|
||||
if (product.isActive) {
|
||||
return res.status(400).json({ message: 'Product is already active' });
|
||||
}
|
||||
|
||||
res.status(200).json(products);
|
||||
// Activate the product
|
||||
product.isActive = true;
|
||||
|
||||
// Save the updated product
|
||||
await product.save();
|
||||
|
||||
res.json({ message: 'Product activated successfully', product });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
res.status(500).json({ message: 'Internal Server Error' });
|
||||
}
|
||||
};
|
||||
|
||||
// Controller function for retrieving all active products (accessible to both admin and normal user)
|
||||
exports.getActiveProducts = async (req, res) => {
|
||||
exports.archiveProduct = async (req, res) => {
|
||||
const { productId } = req.params;
|
||||
|
||||
try {
|
||||
const activeProducts = await Product.find({ isActive: true });
|
||||
// Find the product by ID
|
||||
const product = await Product.findById(productId);
|
||||
|
||||
res.status(200).json(activeProducts);
|
||||
if (!product) {
|
||||
return res.status(404).json({ message: 'Product not found' });
|
||||
}
|
||||
|
||||
// Check if the product is already active
|
||||
if (!product.isActive) {
|
||||
return res.status(400).json({ message: 'Product is already in Archive' });
|
||||
}
|
||||
|
||||
// Activate the product
|
||||
product.isActive = false;
|
||||
|
||||
// Save the updated product
|
||||
await product.save();
|
||||
|
||||
res.json({ message: 'Product successfuly archived', product });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
res.status(500).json({ message: 'Internal Server Error' });
|
||||
}
|
||||
};
|
||||
|
@ -0,0 +1,89 @@
|
||||
**** Accounts ****
|
||||
|
||||
User: ( Password: wapatu )
|
||||
{
|
||||
"userId": "65544d9be5c01f6c0ca79200",
|
||||
"email": "wapatu@example.com",
|
||||
"firstName": "Estevan",
|
||||
"lastName": "Cummings",
|
||||
"isAdmin": false,
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTU0NGQ5YmU1YzAxZjZjMGNhNzkyMDAiLCJlbWFpbCI6IndhcGF0dUBleGFtcGxlLmNvbSIsImlzQWRtaW4iOmZhbHNlLCJpYXQiOjE3MDAwMjM3MjQsImV4cCI6MTcwMDAyNzMyNH0.dpWV9Zx64TH4RLgmV_RlyrMBCa0HwDe9wJRAkwAyjys"
|
||||
}
|
||||
|
||||
Admin: (Password is: admin )
|
||||
{
|
||||
"userId": "65535cb526b586a3e2fd56cc",
|
||||
"email": "admin@email.com",
|
||||
"isAdmin": true,
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTUzNWNiNTI2YjU4NmEzZTJmZDU2Y2MiLCJlbWFpbCI6ImFkbWluQGVtYWlsLmNvbSIsImlzQWRtaW4iOnRydWUsImlhdCI6MTcwMDAyMzgxMSwiZXhwIjoxNzAwMDI3NDExfQ.DrhpNlBJKpfHod7MfTalQ5j2-s8tnR630yh2-_EIYWw"
|
||||
}
|
||||
|
||||
**** Links ****
|
||||
|
||||
REGISTER
|
||||
http://localhost:3000/user/register
|
||||
--> Use post
|
||||
{
|
||||
"email": "admin@email.com",
|
||||
"password": "admin"
|
||||
}
|
||||
|
||||
LOGIN
|
||||
http://localhost:3000/user/login
|
||||
--> Use post
|
||||
{
|
||||
"email": "admin@email.com",
|
||||
"password": "admin"
|
||||
}
|
||||
|
||||
UPDATE PROFILE
|
||||
http://localhost:3000/user/update
|
||||
--> Must use Admin token // use put
|
||||
{
|
||||
"userId": "6554473388d9942bbf4de065",
|
||||
"newEmail": "mundo@email.com",
|
||||
"newFirstname": "Ron",
|
||||
"newLastName": "Pogi",
|
||||
"newPassword": "mundo"
|
||||
}
|
||||
|
||||
CREATE PRODUCT [ADMIN]
|
||||
http://localhost:3000/user/products
|
||||
--> Must use Admin token // use post
|
||||
{
|
||||
"name": "Poring Card",
|
||||
"description": "Description unknown",
|
||||
"price": 500
|
||||
}
|
||||
|
||||
GET ALL PRODUCT
|
||||
http://localhost:3000/user/all
|
||||
--> Use get
|
||||
|
||||
GET ALL ACTIVE PRODUCT
|
||||
http://localhost:3000/user/active
|
||||
--> Use get
|
||||
|
||||
GET A SINGLE PROUCT
|
||||
http://localhost:3000/user/products/65538bd4a601aa30730f6d4c
|
||||
--> Use get
|
||||
|
||||
UPDATE A PRODUCT [ADMIN]
|
||||
http://localhost:3000/user/products/65545a1e6fa9d841e1518d1d
|
||||
--> Must use Admin token // Use put
|
||||
{
|
||||
"name": "Christmas Cookie Card",
|
||||
"description": "Updated Product Description",
|
||||
"price": 29.99,
|
||||
"isActive": false
|
||||
}
|
||||
|
||||
ACTIVATE / ARCHIVE A PRODUCT [ADMIN]
|
||||
--> Use Put
|
||||
http://localhost:3000/user/products/6554634e5cac4bcd6f2394ed/activate
|
||||
http://localhost:3000/user/products/6554634e5cac4bcd6f2394ed/archive
|
||||
|
||||
|
||||
RETRIEVE OWN USER DATA
|
||||
--> Use Get
|
||||
http://localhost:3000/user/65535cb526b586a3e2fd56cc
|
@ -1,18 +1,32 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const productController = require('../controllers/product');
|
||||
const auth = require('./auth'); // Assuming you have an auth.js file with authentication middleware
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const productController = require("../controllers/product")
|
||||
const auth = require("../auth")
|
||||
|
||||
// Middleware for authorization token
|
||||
const authenticateToken = auth.authenticateToken;
|
||||
const { authenticateToken, verifyAdmin } = auth
|
||||
|
||||
// S50
|
||||
// Create a product route (accessible only by isAdmin)
|
||||
router.post('/create', authenticateToken, productController.createProduct);
|
||||
router.post("/products", authenticateToken, verifyAdmin, productController.createProduct)
|
||||
|
||||
// Retrieve all products route (accessible to both admin and normal user)
|
||||
router.get('/all', productController.getAllProducts);
|
||||
router.get("/all", productController.getAllProducts)
|
||||
|
||||
// Retrieve all active products route (accessible to both admin and normal user)
|
||||
router.get('/active', productController.getActiveProducts);
|
||||
router.get("/active", productController.getActiveProducts)
|
||||
|
||||
module.exports = router;
|
||||
// S51
|
||||
// Retrieve a single product by ID
|
||||
router.get('/products/:id', productController.getProductById);
|
||||
|
||||
// Update product route + admin verification
|
||||
router.put('/products/:id', authenticateToken, verifyAdmin, productController.updateProduct);
|
||||
|
||||
// Archive a product
|
||||
router.put('/products/:productId/archive', authenticateToken, verifyAdmin, productController.archiveProduct);
|
||||
|
||||
// Activate a product
|
||||
router.put('/products/:productId/activate', authenticateToken, verifyAdmin, productController.activateProduct);
|
||||
|
||||
|
||||
module.exports = router
|
||||
|
Loading…
Reference in New Issue