You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A full-stack social media platform where users can share posts with images, like and comment on content, follow other users, and check live weather — all in a responsive three-column feed layout.
The VITE_CLOUDINARY_UPLOAD_PRESET must be an unsigned upload preset configured in your Cloudinary dashboard, used for direct browser uploads of post images.
4. Install dependencies and run
# Backendcd explorerServer
npm install
npm run dev # or: node src/server.js# Frontend (in a new terminal)cd explorerClient
npm install
npm run dev
The frontend will be available at http://localhost:5173 and the API at http://localhost:3333.
API Reference
All protected endpoints require:
Authorization: Bearer <access_token>
Users — /api/v1/users
Method
Path
Auth
Description
POST
/register
No
Register a new user (multipart/form-data with avatar file)
POST
/login
No
Log in; returns access + refresh tokens
POST
/logout
Yes
Log out; clears tokens and cookies
POST
/refresh-token
No
Refresh the access token using a valid refresh token
GET
/current-user
Yes
Get the currently authenticated user
GET
/profile/:userId
Yes
Get a user's profile, posts, followers, and following
POST
/follow-user/:userId
Yes
Toggle follow / unfollow
Posts — /api/v1/posts
Method
Path
Auth
Description
GET
/
Yes
Get all posts with like/comment data
POST
/create-post
Yes
Create a new post (title + Cloudinary image URL)
GET
/myposts
Yes
Get the current user's posts
DELETE
/deletepost/:postId
Yes
Delete own post
POST
/post/:postId
Yes
Toggle like / unlike
Comments — /api/v1/comments
Method
Path
Auth
Description
POST
/post/:postId
Yes
Add a comment to a post
Authentication Flow
Register → bcrypt hash password → upload avatar to Cloudinary → create User in MongoDB
Login → verify password → generate JWT access + refresh tokens → set cookies + return in JSON body
Request → verifyJWT middleware reads token from cookie or Authorization header
→ decode → fetch user from DB → attach to req.user
Logout → remove refreshToken from DB → clear cookies
Database Models
User
Field
Type
Notes
name
String
email
String
unique
avatar
String
Cloudinary URL
password
String
bcrypt hashed
followers
[ObjectId]
ref: User
following
[ObjectId]
ref: User
refreshToken
String
cleared on logout
Post
Field
Type
Notes
title
String
post caption
image
String
Cloudinary URL
postedBy
ObjectId
ref: User
Comment
Field
Type
Notes
content
String
postId
ObjectId
ref: Post
author
ObjectId
ref: User
SocialLike
Field
Type
Notes
postId
ObjectId
ref: Post
likedBy
ObjectId
ref: User
Key Design Decisions
Direct Cloudinary upload for posts: Post images are uploaded from the browser directly to Cloudinary (using an unsigned preset), and only the resulting URL is sent to the backend. This avoids large binary payloads hitting the Node.js server for every post.
Server-side Cloudinary upload for avatars: Avatars are uploaded via the server during registration (using Multer + Cloudinary SDK) because it runs as part of the form validation / user-creation transaction.
Dual token delivery: Access and refresh tokens are sent as both httpOnly cookies (XSS-safe for browsers) and in the JSON body (usable by mobile/API clients without cookie support).
asyncHandler utility: All async Express controllers are wrapped in a higher-order function that forwards thrown errors to next(), removing boilerplate try/catch in every route.
PostContext for feed state: Posts are stored in React context so that like, delete, and create actions update the feed instantly without re-fetching the entire list from the server.