Capkeybara is THE ultimate e-commerce platform for top-notch mechanical keyboard components that cater to all your needs!
Whether you're a seasoned keyboard enthusiast, a newbie exploring the world of mechanical keyboards, or simply on the hunt for a quick upgrade, we've got you covered! We are here guide you with expert advice to ensure you make the perfect choice every time you hit that "add to cart" button!
- Frontend Repository (ReactJS - useForm, Toastify, Styled Components)
- Backend Repository (NodeJS - Express, Handlebars, Bookshelf ORM with knex, DB-migrate, Cloudinary, Stripe, and MySQL)
Given the relationship between entities, a relational DB (in this case MySQL) would be more ideal to store the data. The schema is as shown below.
Do note that the password field will be hashed using bcrypt before it is stored in the DB.
The following has not been implemented
Discounts
for products2FA
for account signups forgot and update password (nodemailer)
Base URL for buyers http://capkeybara-backend.onrender.com/api/buyers
.
Endpoint | Method | Description | Request Body | Response | Authentication Response |
---|---|---|---|---|---|
/ |
GET | Get information of all buyers | Status 200 - returns data of all buyers Status 500 - returns an error message |
||
/ |
POST | Creates a new buyer (Incomplete data) |
{ "username": string, "email": string, "password": string, "confirm_password": string } |
Status 200 - returns a message requesting for more signup details Status 409 - returns an error message indicating that the buyer username and/or email already exist Status 500 - returns an error message |
|
/ |
POST | Creates a new buyer (Full data) |
{ "username": string, "email": string, "password": string, "confirm_password": string, "first_name": string, "last_name": string, "contact": string, "address": string } |
Status 201 - returns a success message and data of the new buyer created Status 400 - returns an error message indicating an error during new account creation Status 500 - returns an error message |
|
/:buyerId |
GET | Get information of a buyer with ID buyerId | Status 200 - returns a success message and data of the found buyer Status 400 - returns an error message indicating that the buyer is not found Status 500 - returns an error message |
||
/profile |
POST | Get profile of an authenticated buyer | Valid access token retrieved from cookies | Status 200 - returns payload of the authenticated buyer Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
/login |
POST | Verifies the login credential of a buyer | { "username": string, "password": string } |
Status 201 - returns a success message Status 401 - returns an error message indicating invalid login credentials Status 500 - returns an error message |
|
/refresh |
POST | Refresh an expired access token using the refresh token | Valid refresh token retrieved from cookies | Status 200 - returns a new access token Status 500 - returns an error message |
Status 401 - returns an error message indicating no refresh token found Status 403 - returns an error message indicating an invalid refresh token |
/logout |
POST | Removes the access and refresh tokens from cookie, and blacklists refresh token when a buyer logs out | Valid refresh token retrieved from cookies | Status 204 - no response Status 500 - returns an error message |
Status 401 - returns an error message indicating no refresh token found Status 403 - returns an error message indicating an invalid refresh token |
Potential Improvement for Buyers API route
- Hashing password in the frontend before it is sent to the backend.
Currently the new buyer data is sent over to the backend, with the password and confirm-password field being strings. This will be subject to MITM attacks. A better alternative is to hash the passwords after the new buyer has submitted his/her datato prevent information from being stolen during transmission. - Filtering the payload information for buyer profile before it is sent to the frontend.
Upon successful decryption of buyer access token, the payload containing the id, email, first name, username and role of the buyer is returned. Additionally, the 'exp' and 'iat' of the payload is also returned. These information can be filtered out before sending back the data of the buyer to the frontend as they are crucial information for hackers who make use of the access tokens.
Base URL for sellers http://capkeybara-backend.onrender.com/api/sellers
.
Endpoint | Method | Description | Request Body | Response | Authentication Response |
---|---|---|---|---|---|
/ |
GET | Get information of all sellers | Status 200 - returns data of all sellers Status 500 - returns an error message |
||
/ |
POST | Creates a new seller (Incomplete data) |
{ "username": string, "email": string, "password": string, "confirm_password": string } |
Status 200 - returns a message requesting for more signup details Status 409 - returns an error message indicating that the seller username and/or email already exist Status 500 - returns an error message |
|
/ |
POST | Creates a new seller (Full data) |
{ "username": string, "email": string, "password": string, "confirm_password": string, "name": string, "contact": string, "image_url": string } |
Status 201 - returns a success message and data of the new seller created Status 400 - returns an error message indicating an error during new account creation Status 500 - returns an error message |
|
/:sellerId |
GET | Get information of a seller with ID sellerId | Status 200 - returns a success message and data of the found seller Status 400 - returns an error message indicating that the seller is not found Status 500 - returns an error message |
||
/profile |
POST | Get profile of an authenticated seller | Valid access token retrieved from cookies | Status 200 - returns payload of the authenticated seller Status 500 - returns an error message |
Status 401 - returns an error message requiring sellers to login Status 403 - returns an error message indicating an invalid access token |
/login |
POST | Verifies the login credential of a seller | { "username": string, "password": string } |
Status 201 - returns a success message Status 401 - returns an error message indicating invalid login credentials Status 500 - returns an error message |
|
/refresh |
POST | Refresh an expired access token using the refresh token | Valid refresh token retrieved from cookies | Status 200 - returns a new access token Status 500 - returns an error message |
Status 401 - returns an error message indicating no refresh token found Status 403 - returns an error message indicating an invalid refresh token |
/logout |
POST | Removes the access and refresh tokens from cookie, and blacklists refresh token when a seller logs out | Valid refresh token retrieved from cookies | Status 204 - no response Status 500 - returns an error message |
Status 401 - returns an error message indicating no refresh token found Status 403 - returns an error message indicating an invalid refresh token |
Potential Improvement for Sellers API route are similar to that of Buyers.
- There should also be a validity check done on the sellers (possibly using the vendor's UEN), before allowing them to list their products on the website. An additional column can be added to the 'sellers' table in the database to store this information.
Base URL for products http://capkeybara-backend.onrender.com/api/products
.
Endpoint | Method | Description | Request Body | Response | Authentication Response |
---|---|---|---|---|---|
/ |
GET | Get information of all products | Status 200 - returns data of all products Status 500 - returns an error message |
||
/categories |
GET | Get information of all product categories | Status 200 - returns data of all product categories Status 500 - returns an error message |
||
/seller/:sellerId |
GET | Get all products of a seller with ID sellerId | Status 200 - returns a success message and data of all products of the specified seller Status 404 - returns an error message indicating that the specified seller does not exist Status 500 - returns an error message |
||
/ |
POST | Creates a new product | { "name": string, "description": string, "price": float, "cost": float, "quantity_available": integer, "image_url": string, "category_id": integer, "seller_id": integer } |
Status 200 - returns a success message indicating that the new product has been created Status 400 - returns an error message indicating any missing required fields Status 500 - returns an error message |
Status 401 - returns an error message requiring sellers to login Status 403 - returns an error message indicating an invalid access token |
/:productId |
GET | Get information of product with ID productId | Status 200 - returns a success message and data of the specified product Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
||
/:productId |
PUT | Updates an existing product with ID productId | { "name": string, "description": string, "price": float, "cost": float, "quantity_available": integer, "image_url": string, "category_id": integer, "seller_id": integer } |
Status 200 - returns a success message and the data of the product that was updated Status 400 - returns an error message indicating any missing or invalid fields Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring sellers to login Status 403 - returns an error message indicating an invalid access token |
/:productId |
DELETE | Deletes an existing product with ID productId | Status 200 - returns a success message and the data of the product that was deleted Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring sellers to login Status 403 - returns an error message indicating an invalid access token |
|
/search |
POST | Search for existing products based on the search terms | { "searched_name": string, "searched_brands": array, "searched_categories": array, "searched_availability": string, "searched_price_min": float, "searched_price_max": float } |
Status 200 - returns a success message and the data of the product that was searched Status 404 - returns an error message indicating that the specified products cannot be found Status 500 - returns an error message |
Potential Improvement for Products API route
- Role specification.
Currently, any users with a valid access token can perform CRUD operations on the products. Role specification can be added to allow only users with 'seller' and 'admin' roles (and valid access tokens) to manage the products.
Base URL for cart http://capkeybara-backend.onrender.com/api/cart
.
Endpoint | Method | Description | Request Body | Response | Authentication Response |
---|---|---|---|---|---|
/:buyerId |
GET | Retrieves the cart items of buyer with ID buyerId | Status 200 - returns a success message and the data of the cart items of the specified buyer Status 403 - returns an error message indicating that the specified buyer cannot view another buyer's cart Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
|
/:buyerId |
POST | Add or increase the quantity by 1 of a cart item for buyer with ID buyerId | { "product_id": int } |
Status 200 - returns a success message and the data of the cart item added Status 400 - returns an error message indicating that the quantity to be added exceeded the quantity available Status 403 - returns an error message indicating that the specified buyer cannot view another buyer's cart Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
/remove/:buyerId |
POST | Reduce the quantity of a cart item by 1 for buyer with ID buyerId | { "product_id": int } |
Status 200 - returns a success message and the data of the cart item reduced Status 400 - returns an error message indicating that the cart item do not exist or quantity cannot be negative Status 403 - returns an error message indicating that the specified buyer cannot view another buyer's cart Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
/:buyerId |
PUT | Add or increase the quantity of a cart item for buyer with ID buyerId | { "product_id": int "new_quantity": int } |
Status 200 - returns a success message and the data of the cart item updated Status 400 - returns an error message indicating that the quantity to be added exceeded the quantity available Status 403 - returns an error message indicating that the specified buyer cannot view another buyer's cart Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
/:buyerId |
DELETE | Remove a cart item entirely for buyer with ID buyerId | { "product_id": int } |
Status 200 - returns a success message and the data of the cart item removed Status 400 - returns an error message indicating that the cart item was not removed Status 403 - returns an error message indicating that the specified buyer cannot view another buyer's cart Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
Potential Improvement for Cart API route
- Role specification.
Currently, any users with a valid access token can perform CRUD operations on the cart items. Role specification can be added to allow only users with 'buyer' and 'admin' roles (and valid access tokens) to manage their cart items. - More specific error validation.
The error that returns status 400 is does not take into other instances where, for example, users enter data of inapproperiate datatype.
Base URL for orders http://capkeybara-backend.onrender.com/api/orders
.
Endpoint | Method | Description | Request Body | Response | Authentication Response |
---|---|---|---|---|---|
/:buyerId |
GET | Retrieves all orders of buyer with ID buyerId | Status 200 - returns a success message and the data of the orders of the specified buyer Status 404 - returns an error message indicating that the specified product does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
|
/seller/:sellerId |
GET | Retrieves all orders of seller with ID sellerId | Status 200 - returns a success message and the data of the orders of the specified seller Status 403 - returns an error message indicating that the specified seller cannot view another seller's orders Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
|
/:buyerId |
POST | Creates a new order for buyer with buyerId based on his/her cart items | Status 200 - returns a success message and the data of the order created for the specified buyer Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
|
/:orderId |
PUT | Updates the order status of order with ID orderId | { "order_status": string } |
Status 200 - returns a success message and the data of the updated order Status 400 - returns an error message indicating that the specified order was not updated Status 404 - returns an error message indicating that the specified order does not exist Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
Potential Improvement for Order API route
- Segregation of order status based on sellers.
Since a order can consist of many products from different sellers, the order status for a order should be separated for each seller. Currently, the order status will update across all sellers with the same order, instead, the order status could be updated from 'Unfulfilled' to 'Completed' after all sellers have updated the status of the order to 'Delivered'.
Base URL for checkout http://capkeybara-backend.onrender.com/api/checkout
.
Endpoint | Method | Description | Request Body | Response | Authentication Response |
---|---|---|---|---|---|
/:userId |
GET | Creates a Stripe session for user with ID userId by retrieving their cart items from the Cart API | Status 200 - returns a session ID Status 403 - returns an error message indicating that the specified buyer cannot process another buyer's payment Status 500 - returns an error message |
Status 401 - returns an error message requiring buyers to login Status 403 - returns an error message indicating an invalid access token |
JSON Web Tokens (JWT) are used for user authorisation and protection of API routes.
In Capkeybara's case, the JWT generated by the backend, after a user has successfully logged in, is stored using HttpOnly Cookies. The flow is illustrated in the sequence diagram below.
Cookies was chosen over session and localStorage due to its ability to protect against Cross-Site Scripting (XSS) attacks.The HttpOnly
flag prevents malicious scripts from accessing the cookies, thus providing a better safeguard for user sessions and sensitive information.
A request is sent using a refreshToken to get a new accessToken whenever the accessToken is close to expiry. If the new token fails to be generated, the user has to log in again. Upon log out, the refresh token is added to a black list, preventing it from being reused.
The product API routes allows sellers and admin to create, update and delete products with ease. The product information are also displayed on the frontend, allowing easy management.
The cart API routes allows buyers to add, update and delete their cart items. These cart items will also be displayed on the frontend, allow buyers to view their cart items before checking out.
The order API routes allows buyers to create their orders upon successful payment, and also allows sellers to view and manage their orders on the client.
The third party platform, also known as a SASS, Stripe, was used to handle payment processing.
- Reduce the time and money required to implement such capability. This will allow resources to be diverted to developing other areas of Capkeybara.
- Secure data and prevent legal repercussions in the case of a data breach. Since Stripe stores the users' sensitive information such as their credit card information, any form of data breach and security incidents will be borne by Stripe rather than Capkeybara.
- ReactJS - Route access restriction, navigation between pages, form control using useForm
- Cloudinary - Image upload widget for buyer and seller and product images
- NodeJS - Server environment. ExpressJS, Handlebars for admin page templating, Sessions, JWT with bcrypt for Authentication, Bookshelf ORM with knex, Stripe for payment processing and caolan form for form control.
- MySQL - Database management, used in conjuntion with db-migrate
- React Frontend - Main Page (Netlify)
- Express Backend - Admin Page (Render)
(Note that Admin Page is not yet implemented)
Account Type | Name | Password | |
---|---|---|---|
Buyer | Peter Pan | peterpan@neverland.com | peterpan123@ |
Buyer | Tinker Bell | tinkerbell@neverland.com | tinkerbell123@ |
Buyer | Captain Hook | captainhook@neverland.com | captainhook123@ |
Seller | Epomaker | shop@epomaker.com | epomaker123@ |
Seller | Aula | shop@aula.com | aula123@ |
Seller | Keychron | shop@keychron.com | keychron123@ |
No test admin account will be provided.