From ee9419584fb6ebbabfd5962435e2467c044e814c Mon Sep 17 00:00:00 2001 From: snaked2018 Date: Fri, 17 Nov 2023 18:59:20 +0800 Subject: [PATCH] S52 Capstone 2 Added --- .../csp2-reciproco/controllers/user.js | 26 +- .../backend/csp2-reciproco/csp2-postman.json | 135 ++++---- individual/backend/csp2-reciproco/index.js | 3 +- individual/backend/csp2-reciproco/readme.md | 316 ++++++++++-------- .../backend/csp2-reciproco/routes/product.js | 6 +- 5 files changed, 254 insertions(+), 232 deletions(-) diff --git a/individual/backend/csp2-reciproco/controllers/user.js b/individual/backend/csp2-reciproco/controllers/user.js index adcd048..d8b7e6e 100644 --- a/individual/backend/csp2-reciproco/controllers/user.js +++ b/individual/backend/csp2-reciproco/controllers/user.js @@ -155,7 +155,7 @@ exports.updateUserData = async (req, res) => { exports.getUserDetails = async (req, res) => { try { - const { userId } = req.body; + const { userId } = req.body; const user = await User.findById(userId); @@ -163,16 +163,28 @@ exports.getUserDetails = async (req, res) => { return res.status(404).json({ message: "User not found" }); } + // Create a new object with only the desired properties (excluding password) + const userWithoutPassword = { + _id: user._id, + username: user.username, + email: user.email, + firstName: user.firstName, + lastName: user.lastName, + orderedProducts: user.orderedProducts, + // Add other properties you want to include in the response + }; + // Return the user details in the response res.status(200).json({ - user, + user: userWithoutPassword, }); } catch (error) { console.error(error); - res.status(500).json({ message: "Internal server error" }); + res.status(500).json({ message: false }); } }; + exports.setAdmin = async (req, res) => { try { @@ -194,11 +206,3 @@ exports.setAdmin = async (req, res) => { } } -exports.getAllOrders = async (req, res) => { - try { - const orders = await User.find({}, "orderedProducts"); - res.status(200).json({ success: true, data: orders }); - } catch (error) { - res.status(500).json({ success: false, error: error.message }); - } - }; \ No newline at end of file diff --git a/individual/backend/csp2-reciproco/csp2-postman.json b/individual/backend/csp2-reciproco/csp2-postman.json index 7c04a93..931f9d4 100644 --- a/individual/backend/csp2-reciproco/csp2-postman.json +++ b/individual/backend/csp2-reciproco/csp2-postman.json @@ -39,8 +39,18 @@ "response": [] }, { - "name": "User Authenticate", + "name": "User Authenticate/Login", "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTU0NGQ5YmU1YzAxZjZjMGNhNzkyMDAiLCJlbWFpbCI6IndhcGF0dUBlbWFpbC5jb20iLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNzAwMjE0NTcwLCJleHAiOjE3MDAyMTgxNzB9.IMrvxc4l2A5cwMATP3FuCIiZUmaS-eewpqLz5CORQQA", + "type": "string" + } + ] + }, "method": "POST", "header": [], "body": { @@ -78,7 +88,7 @@ "bearer": [ { "key": "token", - "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTUzNjU0NDk4YzFiYmRhMzNmODJiZjAiLCJlbWFpbCI6ImRpdmluZUBleGFtcGxlLmNvbSIsImlhdCI6MTY5OTk3NTczNSwiZXhwIjoxNjk5OTc5MzM1fQ.oWOhcmPp_5-c4vcSncTdfZWpTCybBQejZaLy3RiNV-E", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTU0NGQ5YmU1YzAxZjZjMGNhNzkyMDAiLCJlbWFpbCI6IndhcGF0dUBlbWFpbC5jb20iLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNzAwMjE0NTcwLCJleHAiOjE3MDAyMTgxNzB9.IMrvxc4l2A5cwMATP3FuCIiZUmaS-eewpqLz5CORQQA", "type": "string" } ] @@ -87,7 +97,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\r\n \"userId\": \"6553654498c1bbda33f82bf0\",\r\n \"newEmail\": \"divine@example.com\",\r\n \"newFirstname\": \"Ron\",\r\n \"newLastName\": \"Pogi\",\r\n \"newPassword\": \"crypto123\"\r\n}\r\n", + "raw": "{\r\n \"userId\": \"65544d9be5c01f6c0ca79200\",\r\n \"newEmail\": \"user@email.com\",\r\n \"newFirstname\": \"Ron\",\r\n \"newLastName\": \"Pogi\",\r\n \"newPassword\": \"user\"\r\n}\r\n", "options": { "raw": { "language": "json" @@ -110,39 +120,19 @@ "response": [] }, { - "name": "Product Get All", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3000/user/all", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3000", - "path": [ - "user", - "all" - ] - } - }, - "response": [] - }, - { - "name": "Product Get All [Active]", + "name": "Retrieve Active Products", "request": { "method": "GET", "header": [], "url": { - "raw": "http://localhost:3000/user/active", + "raw": "http://localhost:3000/product/active", "protocol": "http", "host": [ "localhost" ], "port": "3000", "path": [ - "user", + "product", "active" ] } @@ -150,19 +140,19 @@ "response": [] }, { - "name": "Get a Single Product", + "name": "Retrieve Single Product", "request": { "method": "GET", "header": [], "url": { - "raw": "http://localhost:3000/user/products/65545619b88d0a48f00ae778", + "raw": "http://localhost:3000/product/products/65545619b88d0a48f00ae778", "protocol": "http", "host": [ "localhost" ], "port": "3000", "path": [ - "user", + "product", "products", "65545619b88d0a48f00ae778" ] @@ -171,7 +161,7 @@ "response": [] }, { - "name": "Order / User Checkout [Non-admin]", + "name": "User Checkout(Create Order)", "request": { "method": "POST", "header": [], @@ -210,7 +200,7 @@ "bearer": [ { "key": "token", - "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTU0YWM4ZGQ3ZmJmOWVlOTAyMTdlNzciLCJlbWFpbCI6Im1hc3RlckBlbWFpbC5jb20iLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNzAwMDUwOTkzLCJleHAiOjE3MDAwNTQ1OTN9._K7A7ZmE4ApbmE1qtpPYRmiugYn7HpgsIOAW7yR0pUA", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTU0NGQ5YmU1YzAxZjZjMGNhNzkyMDAiLCJlbWFpbCI6IndhcGF0dUBlbWFpbC5jb20iLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNzAwMjE0NTcwLCJleHAiOjE3MDAyMTgxNzB9.IMrvxc4l2A5cwMATP3FuCIiZUmaS-eewpqLz5CORQQA", "type": "string" } ] @@ -219,7 +209,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\r\n \"userId\": \"6554ac8dd7fbf9ee90217e77\"\r\n}\r\n", + "raw": "{\r\n \"userId\": \"65544d9be5c01f6c0ca79200\"\r\n}\r\n", "options": { "raw": { "language": "json" @@ -240,53 +230,34 @@ } }, "response": [] - }, + } + ] + }, + { + "name": "Admin", + "item": [ { - "name": "Retrieve Authenticated user's orders", + "name": "Retrieve All Products", "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTU0NGQ5YmU1YzAxZjZjMGNhNzkyMDAiLCJlbWFpbCI6IndhcGF0dUBlbWFpbC5jb20iLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNzAwMDUwMzYzLCJleHAiOjE3MDAwNTM5NjN9.Csls5KcCnhERt_QrmcFz7vOkEvDaz8-B79AydV2DKqo", - "type": "string" - } - ] - }, - "method": "POST", + "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"userId\": \"65544d9be5c01f6c0ca79200\"\r\n}\r\n", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "http://localhost:3000/user/getOrders", + "raw": "http://localhost:3000/product/all", "protocol": "http", "host": [ "localhost" ], "port": "3000", "path": [ - "user", - "getOrders" + "product", + "all" ] } }, "response": [] - } - ] - }, - { - "name": "Admin", - "item": [ + }, { - "name": "Product Create[Admin]", + "name": "Create Product", "request": { "auth": { "type": "bearer", @@ -310,22 +281,22 @@ } }, "url": { - "raw": "http://localhost:3000/user/products", + "raw": "http://localhost:3000/product/create", "protocol": "http", "host": [ "localhost" ], "port": "3000", "path": [ - "user", - "products" + "product", + "create" ] } }, "response": [] }, { - "name": "Update a product[Admin]", + "name": "Update Product", "request": { "auth": { "type": "bearer", @@ -349,14 +320,14 @@ } }, "url": { - "raw": "http://localhost:3000/user/products/65545a1e6fa9d841e1518d1d", + "raw": "http://localhost:3000/product/products/65545a1e6fa9d841e1518d1d", "protocol": "http", "host": [ "localhost" ], "port": "3000", "path": [ - "user", + "product", "products", "65545a1e6fa9d841e1518d1d" ] @@ -365,7 +336,7 @@ "response": [] }, { - "name": "Activate Product[Admin]", + "name": "Activate Product", "request": { "auth": { "type": "bearer", @@ -380,14 +351,14 @@ "method": "PUT", "header": [], "url": { - "raw": "http://localhost:3000/user/products/6554634e5cac4bcd6f2394ed/activate", + "raw": "http://localhost:3000/product/products/6554634e5cac4bcd6f2394ed/activate", "protocol": "http", "host": [ "localhost" ], "port": "3000", "path": [ - "user", + "product", "products", "6554634e5cac4bcd6f2394ed", "activate" @@ -397,19 +368,19 @@ "response": [] }, { - "name": "Archive Product[Admin]", + "name": "Archive/Draft Product", "request": { "method": "PUT", "header": [], "url": { - "raw": "http://localhost:3000/user/products/6554634e5cac4bcd6f2394ed/archive", + "raw": "http://localhost:3000/product/products/6554634e5cac4bcd6f2394ed/archive", "protocol": "http", "host": [ "localhost" ], "port": "3000", "path": [ - "user", + "product", "products", "6554634e5cac4bcd6f2394ed", "archive" @@ -440,8 +411,18 @@ "response": [] }, { - "name": "Retrieve all Orders[Admin]", + "name": "Retrieve All Orders", "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTU0YWM4ZGQ3ZmJmOWVlOTAyMTdlNzciLCJlbWFpbCI6Im1hc3RlckBlbWFpbC5jb20iLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNzAwMjEyNjkzLCJleHAiOjE3MDAyMTYyOTN9.J908JWFjN5dKRw0-XJPHa4kD6QAW4M7tv1LOVmbtM_E", + "type": "string" + } + ] + }, "method": "GET", "header": [], "url": { diff --git a/individual/backend/csp2-reciproco/index.js b/individual/backend/csp2-reciproco/index.js index d272228..95ce705 100644 --- a/individual/backend/csp2-reciproco/index.js +++ b/individual/backend/csp2-reciproco/index.js @@ -31,7 +31,8 @@ mongoose }) // Routes -app.use("/user", userRoute, productRoute) +app.use("/user", userRoute) +app.use("/product", productRoute) app.use("/cart", cartRoute) // Server up diff --git a/individual/backend/csp2-reciproco/readme.md b/individual/backend/csp2-reciproco/readme.md index 06a9d7f..9e48535 100644 --- a/individual/backend/csp2-reciproco/readme.md +++ b/individual/backend/csp2-reciproco/readme.md @@ -1,140 +1,176 @@ -> Run: npm start - -**** Stretch Goals **** -+ Set user as Admin ( Admin Only ) -+ Retrieve Authenticated User's Orders -+ Retrieve all orders ( Admin Only ) -+ Add to Cart ( Added Products, Change Product Quantities, Remove Products From Cart, Subtotal for each item, Total price for all items) -+ Authentication Token with expiration (1hr) -+ dotenv -+ faker (Auto Generate Names) -+ getUserDetails function ( Detects if the user tries to get the details of the other useId's + Token auth) -+ Middleware Secure verification that match Token and UserId to next() - -**** 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/retrieveUser -{ - - "userId": "6554ac8dd7fbf9ee90217e77" -} - -CART - Add to Cart ---> Must use token -http://localhost:3000/cart/add-to-cart -{ - "userId": "655396dcc8ea29f42422e214", - "productId": "6553a54566c4c86c39034b55", - "quantity": 5 -} - -CART - Delete Item -http://localhost:3000/cart/remove-from-cart ---> Must use token -{ - "userId": "655396dcc8ea29f42422e214", - "productId": "6553a55666c4c86c39034b59", - "quantity": 1 -} - -CART - Update Quantity -http://localhost:3000/cart//update-quantity ---> Must use token -{ - "userId": "655396dcc8ea29f42422e214", - "productId": "6553a55666c4c86c39034b59", - "quantity": 2000 // Update to the desired quantity -} - -CART - Cart Details [ Total ] ---> Must use token -http://localhost:3000/cart/cart-details -{ - "userId": "655396dcc8ea29f42422e214" -} \ No newline at end of file +## E-COMMERCE API DOCUMENTATION + +**_INSTALLATION COMMAND:_** + +`npm install bcrypt cors dotenv express faker jsonwebtoken mongoose nodemon` + +**_Start_** +npm start + +**_TEST ACCOUNTS:_** + +- Regular User: + - email: user@email.com + - pwd: user +- Admin User: + - email: admin@email.com + - pwd: admin + +**_ROUTES:_** + +- User registration (POST) + - http://localhost:3000/user/register + - auth header required: NO + - request body: + { + "email": "admin@email.com", + "password": "admin" + } + +- User authentication (POST) + - http://localhost:3000/user/login + - auth header required: NO + - request body: + { + "email": "admin@email.com", + "password": "admin" + } + +- Create Product (Admin only) (POST) + - http://localhost:4000/product/create + - auth header required: YES + - request body: + { + "name": "Poring Card", + "description": "Description unknown", + "price": 500 + } + +- Update Profile + - http://localhost:3000/user/update + - auth header required: YES + - request body: + { + "userId": "", + "newEmail": "", + "newFirstname": "", + "newLastName": "", + "newPassword": "" + } + +- Retrieve all products (Admin only) (GET) + - http://localhost:3000/product/all + - auth header required: YES + - request body: none + +- Retrieve all active products (GET) + - http://localhost:3000/product/active + - auth header required: NO + - request body: none + +- Get all products (GET) + - http://localhost:3000/product/active + - auth header required: NO + - request body: none + +- Get a product (GET) + - http://localhost:3000/product/products/65545a1e6fa9d841e1518d1d + - auth header required: YES + - request body: none + +- Update Single product (PUT) + - http://localhost:3000/product/products/65545a1e6fa9d841e1518d1d + - auth header required: YES + - request body: + { + "name": "Christmas Cookie Card", + "description": "Updated Product Description", + "price": 29.99, + "isActive": false + } + +- Create Order (POST) + - http://localhost:3000/user/order + - auth header required: YES + - request body: + { + "userId": "65535cb526b586a3e2fd56cc", // Replace with a valid user ID from your database + "products": [ + { + "productId": "6553a4e897ac8ac9462f96c4", // Replace with a valid product ID from your database + "productName": "Mastering Card", + "quantity": 1 + } + ], + "totalAmount": 500 + } + + +- Activate / Archive Product (PUT) + - auth header required: YES + - request body: none + - http://localhost:3000/product/products/6554634e5cac4bcd6f2394ed/activate + - http://localhost:3000/product/products/6554634e5cac4bcd6f2394ed/archive + +- Set User to Admin (POST) [Admin Only] + - hhttp://localhost:3000/user/set-admin/ + - auth header required: YES + - request body: + { + "userId": + } + +- Retrieve All Orders [Admin Only] (GET) + - http://localhost:3000/user/orders-all + - auth header required: YES + - request body: none + +- Add To Cart (POST) + - http://localhost:3000/cart/add-to-cart + - auth header required: YES + - request body: + { + "userId": "655396dcc8ea29f42422e214", + "productId": "6553a54566c4c86c39034b55", + "quantity": 5 + } + +- Delete Item (DELETE) + - http://localhost:3000/cart/remove-from-cart + - auth header required: YES + - request body: + { + "userId": "655396dcc8ea29f42422e214", + "productId": "6553a54566c4c86c39034b55", + "quantity": 5 + } + +- Update Quantity (PUT) + - http://localhost:3000/cart//update-quantity + - auth header required: YES + - request body: + { + "userId": "655396dcc8ea29f42422e214", + "productId": "6553a55666c4c86c39034b59", + "quantity": 2000 + } + +- Cart Total (GET) + - http://localhost:3000/cart/cart-details + - auth header required: YES + - request body: + { + "userId": "655396dcc8ea29f42422e214" + } + +\***\* Stretch Goals \*\*** + +- Set user as Admin ( Admin Only ) +- Retrieve Authenticated User's Orders +- Retrieve all orders ( Admin Only ) +- Add to Cart ( Added Products, Change Product Quantities, Remove Products From Cart, Subtotal for each item, Total price for all items) +- Authentication Token with expiration (1hr) +- dotenv +- faker (Auto Generate Names) +- getUserDetails function ( Detects if the user tries to get the details of the other useId's + Token auth) +- Middleware Secure verification that match Token and UserId to next() diff --git a/individual/backend/csp2-reciproco/routes/product.js b/individual/backend/csp2-reciproco/routes/product.js index 8db2985..8d158c1 100644 --- a/individual/backend/csp2-reciproco/routes/product.js +++ b/individual/backend/csp2-reciproco/routes/product.js @@ -3,14 +3,14 @@ const router = express.Router() const productController = require("../controllers/product") const auth = require("../auth") -const { authenticateToken, verifyAdmin } = auth +const { authenticateToken, verifyAdmin, } = auth // S50 // Create a product route (accessible only by isAdmin) -router.post("/products", authenticateToken, verifyAdmin, productController.createProduct) +router.post("/create", authenticateToken, verifyAdmin, productController.createProduct) // Retrieve all products route (accessible to both admin and normal user) -router.get("/all", productController.getAllProducts) +router.get("/all", authenticateToken, verifyAdmin, productController.getAllProducts) // Retrieve all active products route (accessible to both admin and normal user) router.get("/active", productController.getActiveProducts)