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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,5 @@ dmypy.json

# Pyre type checker
.pyre/

node_modules/
86 changes: 86 additions & 0 deletions controllers/Friend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Friends API

This is a simple RESTful API for managing friends. It allows you to:

- GET a list of all friends
- GET a single friend by email ID
- POST a new friend
- PUT update a friend's details
- DELETE a friend

By default, the API server will run on `http://localhost:5000`.

## API Reference
```
```
### GET a list of all friends

```http
GET /friends

curl http://localhost:5000/friends
```
#### Response:
```
{
"johnsmith@gamil.com": {
"firstName": "John",
"lastName": "Doe",
"DOB": "22-12-1990"
},
"annasmith@gamil.com": {
"firstName": "Anna",
"lastName": "smith",
"DOB": "02-07-1983"
},
"peterjones@gamil.com": {
"firstName": "Peter",
"lastName": "Jones",
"DOB": "21-03-1989"
}
}
```
### GET a single friend by email ID
```
GET /friends/:email

curl http://localhost:5000/friends/johnsmith@gamil.com
```
#### Response:
```
{
"firstName": "John",
"lastName": "Doe",
"DOB": "22-12-1990"
}
```
## POST a new friend
```
POST /friends

curl -X POST -H "Content-Type: application/json" -d '{"email": "janesmith@gamil.com", "friend": {"firstName": "Jane", "lastName": "Smith", "DOB": "11-05-1995"}}' http://localhost:5000/friends
```
#### Response:
```
Friend added successfully
```
## PUT update a friend's details
```
PUT /friends/:email

curl -X PUT -H "Content-Type: application/json" -d '{"friend": {"firstName": "John", "lastName": "Smith", "DOB": "22-12-1990"}}' http://localhost:5000/friends/johnsmith@gamil.com
```
#### Response:
```
Friend updated successfully
```
## DELETE a friend
```
DELETE /friends/:email

curl -X DELETE http://localhost:5000/friends/peterjones@gamil.com
```
#### Response:
```
Friend deleted successfully
```
55 changes: 55 additions & 0 deletions controllers/authController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const jwt = require("jsonwebtoken"); // Importing the jsonwebtoken module
const { doesExist, authenticatedUser } = require("../helpers/auth");

const user = require("../models/user");

let login = (req, res) => {
const username = req.body.username;
const password = req.body.password;

if (!username || !password) {
return res.status(400).json({
message: "Error logging in. Please provide both username and password.",
}); // Using status code 400 for bad request
}

if (authenticatedUser(username, password)) {
let accessToken = jwt.sign(
{
data: password,
},
"access",
{ expiresIn: 60 * 60 }
);

req.session.authorization = {
accessToken,
username,
};
return res.status(200).send("User successfully logged in");
} else {
return res.status(401).json({
message:
"Invalid login credentials. Please check your username and password.",
}); // Using status code 401 for unauthorized
}
};

let register = (req, res) => {
const username = req.body.username;
const password = req.body.password;

if (username && password) {
if (!doesExist(username)) {
user.addUser(username,password);
return res
.status(201) // Using status code 201 for created
.json({ message: "User successfully registered. You can now log in." });
} else {
return res.status(409).json({ message: "Username already exists." }); // Using status code 409 for conflict
}
}
return res.status(400).json({ message: "Invalid username or password." }); // Using status code 400 for bad request
};

module.exports = { login, register };
90 changes: 90 additions & 0 deletions controllers/friendsController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
const friends = require("../models/friend");

// GET request: Retrieve all friends
let getAllFriends = (req, res) => {
res.status(200).send(friends.getAllFriends());
};

// GET by specific ID request: Retrieve a single friend with email ID
let getFriendByEmail = (req, res) => {
const email = req.params.email;
const friend = friends.getFriend(email);
if (friend) {
res.status(200).json(friend);
} else {
res.status(404).send("Friend not found");
}
};

// POST request: Add a new friend
let addFriend = (req, res) => {
const email = req.body.email;
const friend = req.body.friend;
if (!email || !friend) {
res
.status(400)
.send("Please provide both email and friend in request body");
} else if (!isValidFriend(friend)) {
res
.status(400)
.send(
"Invalid friend object. Please provide a valid friend object with firstName, lastName, and DOB"
);
} else if (friends.getFriend(email)) {
res.status(409).send("Friend with this email already exists");
} else {
friends.addFriend(email, friend);
res
.status(201)
.send("The user" + " " + req.body.firstName + " Has been added!");
}
};

// PUT request: Update the details of a friend with email id
let updateFriend = (req, res) => {
const email = req.params.email;
const friend = req.body.friend;
if (!email || !friend) {
res
.status(400)
.send("Please provide both email and friend in request body");
} else if (!isValidFriend(friend)) {
res
.status(400)
.send(
"Invalid friend object. Please provide a valid friend object with firstName, lastName, and DOB"
);
} else if (!friends.getFriend(email)) {
res.status(404).send("Friend not found");
} else {
friends.updateFriend(email, friend);
res.status(200).send(`Friend with the email ${email} updated.`);
}
};

// DELETE request: Delete a friend by email id
let deleteFriend = (req, res) => {
const email = req.params.email;
if (friends.getFriend(email)) {
friends.deleteFriend(email);
res.status(200).send(`Friend with the email ${email} deleted.`);
} else {
res.status(404).send("Friend not found");
}
};

// Helper function to validate friend object
function isValidFriend(friend) {
if (!friend.firstName || !friend.lastName || !friend.DOB) {
return false;
}
return true;
}

module.exports = {
getAllFriends,
getFriendByEmail,
addFriend,
updateFriend,
deleteFriend,
};
24 changes: 24 additions & 0 deletions helpers/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const user = require("../models/user");

const doesExist = (username) => {
let userswithsamename = user.getUser(username);
if (userswithsamename.length > 0) {
return true;
} else {
return false;
}
};

const authenticatedUser = (username, password) => {
const users = user.getAllUsers();
let validusers = users.filter((user) => {
return user.username === username && user.password === password;
});
if (validusers.length > 0) {
return true;
} else {
return false;
}
};

module.exports = { doesExist, authenticatedUser };
94 changes: 12 additions & 82 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,95 +1,25 @@
const express = require('express');
const jwt = require('jsonwebtoken');
const session = require('express-session')
const routes = require('./router/friends.js')

let users = []

const doesExist = (username)=>{
let userswithsamename = users.filter((user)=>{
return user.username === username
});
if(userswithsamename.length > 0){
return true;
} else {
return false;
}
}

const authenticatedUser = (username,password)=>{
let validusers = users.filter((user)=>{
return (user.username === username && user.password === password)
});
if(validusers.length > 0){
return true;
} else {
return false;
}
}
const routes = require("./routes");
const authMiddleware = require("./middleware/authMiddleware");

const app = express();

app.use(session({secret:"fingerpint"},resave=true,saveUninitialized=true));
// This code sets up session management using the Express session middleware
app.use(
session({
secret: "fingerpint",
resave: true,
saveUninitialized: true,
})
);

app.use(express.json());

app.use("/friends", function auth(req,res,next){
if(req.session.authorization) {
token = req.session.authorization['accessToken'];
jwt.verify(token, "access",(err,user)=>{
if(!err){
req.user = user;
next();
}
else{
return res.status(403).json({message: "User not authenticated"})
}
});
} else {
return res.status(403).json({message: "User not logged in"})
}
});

app.post("/login", (req,res) => {
const username = req.body.username;
const password = req.body.password;

if (!username || !password) {
return res.status(404).json({message: "Error logging in"});
}

if (authenticatedUser(username,password)) {
let accessToken = jwt.sign({
data: password
}, 'access', { expiresIn: 60 * 60 });

req.session.authorization = {
accessToken,username
}
return res.status(200).send("User successfully logged in");
} else {
return res.status(208).json({message: "Invalid Login. Check username and password"});
}
});

app.post("/register", (req,res) => {
const username = req.body.username;
const password = req.body.password;

if (username && password) {
if (!doesExist(username)) {
users.push({"username":username,"password":password});
return res.status(200).json({message: "User successfully registred. Now you can login"});
} else {
return res.status(404).json({message: "User already exists!"});
}
}
return res.status(404).json({message: "Unable to register user."});
});

app.use("/friends", authMiddleware);

const PORT =5000;

app.use("/friends", routes);
app.use("/", routes);

app.listen(PORT,()=>console.log("Server is running"));
19 changes: 19 additions & 0 deletions middleware/authMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const jwt = require("jsonwebtoken");

function auth(req, res, next) {
if (req.session.authorization) {
const token = req.session.authorization.accessToken;
jwt.verify(token, "access", (err, user) => {
if (!err) {
req.user = user;
next();
} else {
return res.status(403).json({ message: "User not authenticated" });
}
});
} else {
return res.status(403).json({ message: "User not logged in" });
}
}

module.exports = auth;
Loading