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
21 changes: 19 additions & 2 deletions final_project/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,26 @@ app.use(express.json());

app.use("/customer",session({secret:"fingerprint_customer",resave: true, saveUninitialized: true}))

app.use("/customer/auth/*", function auth(req,res,next){
//Write the authenication mechanism here
app.use("/customer/auth/*", function auth(req, res, next) {
// 1. Check if session exists and has an access token
if (!req.session || !req.session.accessToken) {
return res.status(401).json({ message: "Unauthorized: No session token" });
}

const token = req.session.accessToken;

// 2. Verify JWT token
jwt.verify(token, "fingerprint_customer", (err, decoded) => {
if (err) {
return res.status(403).json({ message: "Forbidden: Invalid token" });
}

// 3. Save decoded info in req.user to use in downstream routes
req.user = decoded;
next(); // pass control to the next middleware or route handler
});
});


const PORT =5000;

Expand Down
101 changes: 90 additions & 11 deletions final_project/router/auth_users.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,107 @@ const jwt = require('jsonwebtoken');
let books = require("./booksdb.js");
const regd_users = express.Router();

let users = [];
let users = []; // Stores registered users

const isValid = (username)=>{ //returns boolean
//write code to check is the username is valid
// Check if the username is valid (exists in records)
const isValid = (username) => {
return users.some(user => user.username === username);
}

const authenticatedUser = (username,password)=>{ //returns boolean
//write code to check if username and password match the one we have in records.
// Check if username and password match
const authenticatedUser = (username, password) => {
return users.some(user => user.username === username && user.password === password);
}

//only registered users can login
regd_users.post("/login", (req,res) => {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});
// Only registered users can login
regd_users.post("/login", (req, res) => {
const { username, password } = req.body;

// Validate input
if (!username || !password) {
return res.status(400).json({ message: "Username and password are required" });
}

// Check if user exists and password matches
if (authenticatedUser(username, password)) {
// Generate JWT token
const token = jwt.sign({ username }, "fingerprint_customer", { expiresIn: "1h" });

// Save token in session
req.session = req.session || {}; // Ensure session object exists
req.session.accessToken = token;

return res.status(200).json({ message: "User successfully logged in", token });
} else {
return res.status(401).json({ message: "Invalid username or password" });
}
});

// Add a book review
// Add or update a book review
regd_users.put("/auth/review/:isbn", (req, res) => {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});
const isbn = req.params.isbn;
const { review } = req.body;

// Check if user is logged in
if (!req.session || !req.session.accessToken) {
return res.status(401).json({ message: "Unauthorized: Please login first" });
}

// Verify JWT token
jwt.verify(req.session.accessToken, "fingerprint_customer", (err, decoded) => {
if (err) {
return res.status(403).json({ message: "Forbidden: Invalid token" });
}

const username = decoded.username;

// Check if the book exists
if (!books[isbn]) {
return res.status(404).json({ message: `Book with ISBN ${isbn} not found` });
}

// Add or update the review
books[isbn].reviews = books[isbn].reviews || {};
books[isbn].reviews[username] = review;

return res.status(200).json({ message: `Review added/updated for book ${isbn}`, reviews: books[isbn].reviews });
});
});

// Delete a book review
regd_users.delete("/auth/review/:isbn", (req, res) => {
const isbn = req.params.isbn;

// Check if user is logged in
if (!req.session || !req.session.accessToken) {
return res.status(401).json({ message: "Unauthorized: Please login first" });
}

// Verify JWT token
jwt.verify(req.session.accessToken, "fingerprint_customer", (err, decoded) => {
if (err) {
return res.status(403).json({ message: "Forbidden: Invalid token" });
}

const username = decoded.username;

// Check if the book exists
if (!books[isbn]) {
return res.status(404).json({ message: `Book with ISBN ${isbn} not found` });
}

// Check if the user has a review to delete
if (books[isbn].reviews && books[isbn].reviews[username]) {
delete books[isbn].reviews[username]; // Delete the user's review
return res.status(200).json({ message: `Review deleted for book ${isbn}`, reviews: books[isbn].reviews });
} else {
return res.status(404).json({ message: "No review found by this user for the specified book" });
}
});
});


module.exports.authenticated = regd_users;
module.exports.isValid = isValid;
module.exports.users = users;
152 changes: 129 additions & 23 deletions final_project/router/general.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,149 @@
const express = require('express');
const axios = require('axios');
let books = require("./booksdb.js");
let isValid = require("./auth_users.js").isValid;
let users = require("./auth_users.js").users;
const public_users = express.Router();


public_users.post("/register", (req,res) => {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});
// Register a new user
public_users.post("/register", (req, res) => {
const { username, password } = req.body; // Get username and password from request body

// Check if both username and password are provided
if (!username || !password) {
return res.status(400).json({ message: "Username and password are required" });
}

// Check if username already exists
const userExists = users.some(user => user.username === username);
if (userExists) {
return res.status(409).json({ message: "Username already exists" });
}

// Add the new user to the users array
users.push({ username, password });
return res.status(201).json({ message: "User registered successfully" });
});


// Get the book list available in the shop
public_users.get('/',function (req, res) {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});
public_users.get('/', async function (req, res) {
try {
// Simulate an API call with Axios using a local endpoint
// Here, we use a Promise that resolves immediately for demo
const response = await new Promise((resolve, reject) => {
resolve({ data: books });
});

const bookList = JSON.stringify(response.data, null, 4);
return res.status(200).send(bookList);
} catch (error) {
return res.status(500).json({ message: "Error fetching books", error: error.message });
}
});

// Get book details based on ISBN using async-await
public_users.get('/isbn/:isbn', async function (req, res) {
const isbn = req.params.isbn; // Retrieve ISBN from request parameters

try {
// Simulate an async API call using a Promise
const response = await new Promise((resolve, reject) => {
if (books[isbn]) {
resolve({ data: books[isbn] });
} else {
reject(new Error(`Book with ISBN ${isbn} not found`));
}
});

const bookDetails = JSON.stringify(response.data, null, 4);
return res.status(200).send(bookDetails);

} catch (error) {
return res.status(404).json({ message: error.message });
}
});

// Get book details based on ISBN
public_users.get('/isbn/:isbn',function (req, res) {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});
});

// Get book details based on author
public_users.get('/author/:author',function (req, res) {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});
// Get book details based on author using async-await
public_users.get('/author/:author', async function (req, res) {
const authorName = req.params.author; // Retrieve author from request parameters

try {
// Simulate an async API call using a Promise
const response = await new Promise((resolve, reject) => {
const bookKeys = Object.keys(books);
let authorBooks = {};

bookKeys.forEach((isbn) => {
if (books[isbn].author.toLowerCase() === authorName.toLowerCase()) {
authorBooks[isbn] = books[isbn];
}
});

if (Object.keys(authorBooks).length > 0) {
resolve({ data: authorBooks });
} else {
reject(new Error(`No books found by author '${authorName}'`));
}
});

const result = JSON.stringify(response.data, null, 4);
return res.status(200).send(result);

} catch (error) {
return res.status(404).json({ message: error.message });
}
});

// Get all books based on title
public_users.get('/title/:title',function (req, res) {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});


// Get all books based on title using async-await
public_users.get('/title/:title', async function (req, res) {
const titleName = req.params.title; // Retrieve title from request parameters

try {
// Simulate an async API call using a Promise
const response = await new Promise((resolve, reject) => {
const bookKeys = Object.keys(books);
let titleBooks = {};

bookKeys.forEach((isbn) => {
if (books[isbn].title.toLowerCase() === titleName.toLowerCase()) {
titleBooks[isbn] = books[isbn];
}
});

if (Object.keys(titleBooks).length > 0) {
resolve({ data: titleBooks });
} else {
reject(new Error(`No books found with title '${titleName}'`));
}
});

const result = JSON.stringify(response.data, null, 4);
return res.status(200).send(result);

} catch (error) {
return res.status(404).json({ message: error.message });
}
});

// Get book review
public_users.get('/review/:isbn',function (req, res) {
//Write your code here
return res.status(300).json({message: "Yet to be implemented"});

// Get book review
public_users.get('/review/:isbn', function (req, res) {
const isbn = req.params.isbn; // Retrieve ISBN from request parameters

// Check if the book exists
if (books[isbn]) {
const reviews = books[isbn].reviews; // Get the reviews object
const result = JSON.stringify(reviews, null, 4); // Format JSON neatly
return res.status(200).send(result);
} else {
return res.status(404).json({ message: `Book with ISBN ${isbn} not found` });
}
});


module.exports.general = public_users;