forked from dishamodi0910/APIVerse
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request dishamodi0910#196 from Varad0014/newapi
[New API]: Added Social Media API
- Loading branch information
Showing
15 changed files
with
2,490 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
# Description | ||
This API facilitates Social Media Management, providing functionality for users to login, follow each other, post content, comment on posts, and like posts. Only followers are authorised to interact with posts. | ||
|
||
# API Endpoints | ||
## Authentication | ||
### POST /api/auth/register | ||
Register user taking username, password and name in request body. Returns jwt token. | ||
### POST /api/auth/login | ||
Login user taking username and password in request body. Returns jwt token. | ||
|
||
## User Profile Management | ||
### GET /api/users/:userId/profile | ||
Retrieve profile of a specific user. Can be accessed by any authenticated user. | ||
|
||
### PATCH /api/users/:userId/profile | ||
Update profile of a specific user. Can be done by the current user if user id in jwt payload matches userId. | ||
|
||
### DELETE /api/users/:userId/profile | ||
Update profile of a specific user. Can be done by the current user if user id in jwt payload matches userId. | ||
|
||
## User Following Management | ||
### GET /api/users/:userId/following | ||
Get list of following of a specific user. Can be accessed only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
### GET /api/users/:userId/followers | ||
Get list of followers of a specific user. Can be accessed only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
### POST /api/users/:userId/following | ||
Current authenticated user can follow the user with id as userId. | ||
|
||
### DELETE /api/users/:userId/following | ||
Current authenticated user can unfollow the user with id as userId. | ||
|
||
## Post Management | ||
### GET /api/users/:userId/posts | ||
Get list of posts of a specific user. Can be accessed only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
### POST /api/users/:userId/posts | ||
Add a new post for a specific user. Can be done by the current user if user id in jwt payload matches userId. | ||
|
||
### GET /api/users/:userId/posts/:postId | ||
Get post by id of a specific user. Can be accessed only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
### PATCH /api/users/:userId/posts/:postId | ||
Update post by id of a specific user. Can be done by the current user if user id in jwt payload matches userId. | ||
|
||
### DELETE /api/users/:userId/posts/:postId | ||
Delete post by id of a specific user. Can be done by the current user if user id in jwt payload matches userId. | ||
|
||
### POST /api/users/:userId/posts/:postId/like | ||
Add current user's like for a specific post. Can be done only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
### DELETE /api/users/:userId/posts/:postId/like | ||
Remove current user's like for a specific post. Can be done only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
## Comments Management | ||
### GET /api/users/:userId/posts/:postId/comments | ||
Get list of comments of a specific post. Can be accessed only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
### POST /api/users/:userId/posts/:postId/comments | ||
Add a comment to a specific post. Can be done only if current user's id in the jwt payload is present in followers of user with id userId | ||
|
||
### PATCH /api/users/:userId/posts/:postId/comments/:commentId | ||
Upadte a specific comment. Can be done only if current user's id in the jwt payload is present in followers of user with id userId and the comment is written by current user | ||
|
||
### DELETE /api/users/:userId/posts/:postId/comments | ||
Delete a specific comment. Can be done only if current user's id in the jwt payload is present in followers of user with id userId and the comment is written by current user | ||
|
||
|
||
|
||
|
||
|
||
# Getting Started | ||
## Pre-Requisites | ||
Make sure you have: | ||
- Node | ||
- MongoDB | ||
|
||
## Steps to Run | ||
- Clone the repository and navigate to the main directory **SocialMediaAPI** | ||
|
||
```bash | ||
cd SocialMediaAPI | ||
``` | ||
- Create a **.env** file in the main directory | ||
```bash | ||
touch .env | ||
``` | ||
|
||
- Add the following neccessary details in the **.env** file | ||
```bash | ||
PORT=4000 | ||
DBURL=mongodb://localhost:27017/<database name> | ||
``` | ||
- Install dependencies | ||
```bash | ||
npm install | ||
``` | ||
|
||
- Run the server code | ||
```bash | ||
node index.js | ||
``` | ||
|
||
## Request Body Example | ||
### Request body for registration | ||
```bash | ||
{ | ||
"username": "p1", | ||
"name": "p", | ||
"password": "p1" | ||
} | ||
``` | ||
### Request body for login | ||
```bash | ||
{ | ||
"username": "p1", | ||
"password": "p1" | ||
} | ||
``` | ||
### Request body for update profile | ||
```bash | ||
{ | ||
"username": "p1", | ||
"name": "p", | ||
} | ||
``` | ||
### Request body for adding post | ||
```bash | ||
{ | ||
"title": "This is the post title", | ||
"content": "This is the post content" | ||
} | ||
``` | ||
### Request body for updating post | ||
```bash | ||
{ | ||
"title": "This is the updated post title", | ||
"content": "This is the updated post content" | ||
} | ||
``` | ||
### Request body for adding comment | ||
```bash | ||
{ | ||
"text": "This is the text comment", | ||
} | ||
``` | ||
### Request body for updating a comment | ||
```bash | ||
{ | ||
"text": "This is the updated text comment", | ||
} | ||
``` | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
|
||
import jwt from "jsonwebtoken"; | ||
import User from "../models/user.js"; | ||
import dotenv from "dotenv" | ||
|
||
dotenv.config(); | ||
|
||
export default class AuthController { | ||
static async registerUser(req, res, next) { | ||
const { name, username, password } = req.body; | ||
try { | ||
const userExists = await User.findOne({username}); | ||
console.log(userExists); | ||
if(userExists){ | ||
return(res.status(400).json({message: "User with username already exists"})); | ||
} | ||
const user = new User({ name, username, password}); | ||
const newUser = await user.save(); | ||
const token = jwt.sign({ id: newUser._id }, process.env.JWT_SECRET, { expiresIn: '4d' }); | ||
res.status(201).json({ jwt: token }); | ||
} catch (err) { | ||
console.log(err); | ||
res.status(400).json({ message: err }); | ||
} | ||
} | ||
static async loginUser(req, res, next) { | ||
const { username, password } = req.body; | ||
try { | ||
const user = await User.authenticateUser(username, password); | ||
if (user) { | ||
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '4d' }); | ||
res.status(201).json({ jwt: token }); | ||
} | ||
else { | ||
return (res.status(401).json({ message: "Invalid credentials" })); | ||
} | ||
} catch (err) { | ||
console.log(err); | ||
res.status(500).json({ message: err }); | ||
} | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
New_APIs/SocialMediaAPI/controllers/comments.controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
|
||
import Post from "../models/post.js" | ||
import User from "../models/user.js"; | ||
import Comment from "../models/comment.js"; | ||
|
||
export default class CommentController { | ||
static async addPostComment(req, res, next) { | ||
try { | ||
const {userId, postId} = req.params | ||
const {text} = req.body; | ||
const user = await User.findById(userId); | ||
if(!user){ | ||
return res.status(404).send({ error: "No User found" }) | ||
} | ||
if (!user._id.equals(req.user._id) && !user.followers.includes(req.user._id)){ | ||
return (res.status(401).json({ error: "Unauthorized" })); | ||
} | ||
const post = await Post.findOne({userId: user._id, _id: postId}); | ||
if(!post){ | ||
return res.status(404).json({error: "Post not found"}) | ||
} | ||
const comment = new Comment({ | ||
text: text, | ||
userId: req.user._id, | ||
postId: post._id | ||
}) | ||
const response = await comment.save(); | ||
res.status(200).json(response); | ||
} catch (err) { | ||
console.log(err); | ||
res.status(500).json({ error: err }); | ||
} | ||
} | ||
|
||
static async getPostComments(req, res, next) { | ||
try { | ||
const {userId, postId} = req.params | ||
const user = await User.findById(userId); | ||
if(!user){ | ||
return res.status(404).send({ error: "No User found" }) | ||
} | ||
if (!user._id.equals(req.user._id) && !user.followers.includes(req.user._id)){ | ||
return (res.status(401).json({ error: "Unauthorized" })); | ||
} | ||
const post = await Post.findOne({userId: user._id, _id: postId}); | ||
if(!post){ | ||
return res.status(404).json({error: "Post not found"}) | ||
} | ||
const comments = await Comment.find({postId: post._id}); | ||
|
||
const response = comments | ||
res.status(200).json(response); | ||
} catch (err) { | ||
console.log(err); | ||
res.status(500).json({ error: err }); | ||
} | ||
|
||
} | ||
static async updatePostCommentById(req, res, next) { | ||
try { | ||
const {userId, postId, commentId} = req.params | ||
const {text} = req.body; | ||
const user = await User.findById(userId); | ||
if(!user){ | ||
return res.status(404).send({ error: "No User found" }) | ||
} | ||
if (!user._id.equals(req.user._id) && !user.followers.includes(req.user._id)){ | ||
return (res.status(401).json({ error: "Unauthorized" })); | ||
} | ||
const post = await Post.findOne({userId: user._id, _id: postId}); | ||
if(!post){ | ||
return res.status(404).json({error: "Post not found"}) | ||
} | ||
const comment = await Comment.findById(commentId); | ||
if(!comment){ | ||
return res.status(404).json({error: "Comment not found"}) | ||
} | ||
if(!req.user._id.equals(comment.userId) || !post._id.equals(comment.postId)){ | ||
return (res.status(401).json({ error: "Unauthorized" })); | ||
} | ||
comment.text = text; | ||
const response = await comment.save(); | ||
res.status(200).json(response); | ||
} catch (err) { | ||
console.log(err); | ||
res.status(500).json({ error: err }); | ||
} | ||
|
||
} | ||
|
||
|
||
static async deletePostCommentById(req, res, next) { | ||
try { | ||
const {userId, postId, commentId} = req.params | ||
const user = await User.findById(userId); | ||
if(!user){ | ||
return res.status(404).send({ error: "No User found" }) | ||
} | ||
if (!user._id.equals(req.user._id) && !user.followers.includes(req.user._id)){ | ||
return (res.status(401).json({ error: "Unauthorized" })); | ||
} | ||
const post = await Post.findOne({userId: user._id, _id: postId}); | ||
if(!post){ | ||
return res.status(404).json({error: "Post not found"}) | ||
} | ||
const comment = await Comment.findById(commentId); | ||
if(!comment){ | ||
return res.status(404).json({error: "Comment not found"}) | ||
} | ||
if(!req.user._id.equals(comment.userId) || !post._id.equals(comment.postId)){ | ||
return (res.status(401).json({ error: "Unauthorized" })); | ||
} | ||
await Comment.findByIdAndDelete(commentId); | ||
res.status(200).json({ message: "Comment deleted successfully" }); | ||
} catch (err) { | ||
console.log(err); | ||
res.status(500).json({ error: err }); | ||
} | ||
|
||
} | ||
|
||
|
||
} |
Oops, something went wrong.