Version: 1.0.0
Base URL: http://localhost:5000/api/v1
Frontend URL: http://localhost:5173
- Authentication Overview
- Middleware & Security
- API Endpoints
- Data Models
- Error Handling
- Issues & Recommendations
- Access Token: Short-lived token (stored in httpOnly cookies)
- Refresh Token: Long-lived token for refreshing access (stored in httpOnly cookies)
- Token Duration: Access token expires in ~1 hour, Refresh token expires in 7 days
- Cookie-based (primary): Tokens sent via httpOnly cookies
- Bearer Token (fallback): Can send token in
Authorization: Bearer <token>header
ADMIN: Can create/update/delete problemsSTUDENT: Regular user (default role)
1. express.json() - Parse JSON request bodies
2. express.urlencoded() - Parse URL-encoded data
3. cookieParser() - Parse cookies
4. cors() - CORS enabled for frontend (http://localhost:5173)
verifyJWT- Authenticates user via JWT tokencheckAdmin- Verifies user has ADMIN rolevalidate- Validates request body/params against schemaupload.single/array()- Handles file uploads (Multer middleware)
registrationValidation()- Validates signup dataloginValidation()- Validates login credentialschangePasswordValidation()- Validates password changecreateGroupChatValidation()- Validates group creationaddMembersValidation()- Validates member additionremoveMemberValidation()- Validates member removalchatIdValidation()- Validates chat ID formatsendAttachmentValidation()- Validates attachment uploadrenameChatValidation()- Validates rename datasendRequestValidation()- Validates friend requestacceptRequestValidation()- Validates request acceptanceendContestResultValidation()- Validates contest result
POST /auth/register
Auth Required: No
Validation: registrationValidation()
Request Body:
{
"username": "john_doe",
"fullname": "John Doe",
"email": "john@example.com",
"password": "securePass123",
"role": "STUDENT" // Optional: defaults to STUDENT
}Success Response (201):
{
"message": "User created successfully",
"user": {
"id": "user_mongo_id",
"email": "john@example.com",
"role": "STUDENT",
"avatar": "default_avatar_url"
}
}Error Responses:
400- User already exists400- Something went wrong while registering500- Error creating user
POST /auth/login
Auth Required: No
Validation: loginValidation()
Request Body:
{
"email": "john@example.com",
"password": "securePass123"
}Success Response (200):
{
"message": "User logged In successfully",
"user": {
"_id": "user_mongo_id",
"username": "john_doe",
"email": "john@example.com",
"fullname": "John Doe",
"role": "STUDENT",
"avatar": {
"public_id": "cloudinary_public_id",
"url": "https://cloudinary_url..."
}
},
"accessToken": "jwt_access_token",
"refreshToken": "jwt_refresh_token"
}Error Responses:
401- User not found401- Invalid user credentials500- Error login user
POST /auth/logout
Auth Required: Yes (verifyJWT)
Request Body: None
Success Response (200):
{
"message": "User logged Out"
}Error Responses:
401- Unauthorized request500- Error logout user
Side Effects: Clears accessToken and refreshToken cookies
POST /auth/refresh-token
Auth Required: No (but requires refreshToken in cookies)
Request Body: None
Success Response (200):
{
"message": "Access token refreshed",
"tokens": {
"accessToken": "new_jwt_access_token",
"refreshToken": "new_jwt_refresh_token"
}
}Error Responses:
401- Unauthorized request (no refresh token)401- Invalid refresh token401- Refresh token is expired or used500- refreshAccessToken error
GET /auth/check
Auth Required: Yes (verifyJWT)
Request Body: None
Success Response (200):
{
"success": true,
"message": "User authenticated successfully",
"user": {
"_id": "user_mongo_id",
"username": "john_doe",
"email": "john@example.com",
"fullname": "John Doe",
"role": "STUDENT",
"avatar": { ... }
}
}Error Responses:
401- Unauthorized request500- Error checking user
POST /auth/change-password
Auth Required: Yes (verifyJWT)
Validation: changePasswordValidation()
Request Body:
{
"oldPassword": "oldPass123",
"newPassword": "newSecurePass456",
"confirmPassword": "newSecurePass456"
}Success Response (200):
{
"message": "Password changed successfully"
}Error Responses:
404- User not found400- New password must be different from old password400- Mismatch new password and confirm password401- Invalid old password500- Error in changing password
Side Effects: Clears all sessions (revokes refreshToken)
PATCH /auth/update-avatar
Auth Required: Yes (verifyJWT)
Content-Type: multipart/form-data
Request:
- File:
avatar(single image file, multipart) - Field Name:
avatar
Success Response (200):
{
"message": "Avatar updated successfully",
"user": {
"_id": "user_mongo_id",
"username": "john_doe",
"email": "john@example.com",
"fullname": "John Doe",
"avatar": {
"public_id": "new_cloudinary_public_id",
"url": "https://new_cloudinary_url..."
}
}
}Error Responses:
401- Unauthorized request400- Avatar file is missing400- Only image files are allowed400- Error while uploading on cloudinary400- User not found500- updateAvatar error
Storage: Images uploaded to Cloudinary
POST /problems/create-problem
Auth Required: Yes (verifyJWT)
Admin Required: Yes (checkAdmin)
Request Body:
{
"title": "Two Sum",
"description": "Given an array of integers nums...",
"difficulty": "Easy",
"tags": ["array", "hash-table"],
"constraints": "1 <= nums.length <= 10^4",
"hints": ["Use a hash map"],
"examples": [
{
"input": "[2,7,11,15], 9",
"output": "[0,1]",
"explanation": "nums[0] + nums[1] == 9"
}
],
"testcases": [
{ "input": "2 7 11 15", "output": "0 1" },
{ "input": "3 2 4", "output": "0 2" }
],
"codeSnippets": {
"javascript": "var twoSum = function(nums, target) {\n // Code here\n};",
"python": "def twoSum(nums, target):\n # Code here\n pass",
"cpp": "class Solution {\npublic:\n vector<int> twoSum(vector<int>& nums, int target) {\n // Code here\n }\n};"
},
"referenceSolution": {
"javascript": "var twoSum = function(nums, target) { return [0,1]; };",
"python": "def twoSum(nums, target): return [0,1]",
"cpp": "vector<int> twoSum(vector<int>& nums, int target) { return {0, 1}; }"
}
}Success Response (201):
{
"success": true,
"message": "Problem created successfully",
"problem": {
"_id": "problem_mongo_id",
"title": "Two Sum",
"description": "...",
"difficulty": "Easy",
"tags": ["array", "hash-table"],
"createdBy": "admin_user_id",
"testcases": [...],
"__v": 0
}
}Error Responses:
401- Unauthorized request403- Only admin can create problems400- Testcase failed for language X400- Language X is not supported500- Error while creating problem
Validation: Reference solution is validated against all testcases
GET /problems/get-All-problems
Auth Required: Yes (verifyJWT)
Query Params: None
Success Response (200):
{
"success": true,
"message": "All the Problems fetched successfully",
"problems": [
{
"_id": "problem_id_1",
"title": "Two Sum",
"difficulty": "Easy",
"tags": ["array", "hash-table"],
"createdBy": "admin_id",
"createdAt": "2025-03-09T10:30:00Z"
},
{ ... }
]
}Error Responses:
401- Unauthorized request404- No problems found500- Error while fetching Problems
GET /problems/get-problem/:id
Auth Required: Yes (verifyJWT)
URL Params:
id(string): Problem MongoDB ID
Success Response (200):
{
"success": true,
"message": "Problem fetched successfully",
"problem": {
"_id": "problem_id",
"title": "Two Sum",
"description": "Given an array of integers...",
"difficulty": "Easy",
"tags": ["array", "hash-table"],
"constraints": "...",
"hints": ["Use a hash map"],
"examples": [...],
"testcases": [...],
"codeSnippets": {...},
"referenceSolution": {...},
"createdBy": "admin_id"
}
}Error Responses:
401- Unauthorized request404- Problem not found500- Error while fetching Problem
PUT /problems/update-problem/:id
Auth Required: Yes (verifyJWT)
Admin Required: Yes (checkAdmin)
URL Params:
id(string): Problem MongoDB ID
Request Body: Same structure as Create Problem (partial update supported)
Success Response (200):
{
"success": true,
"message": "Problem updated successfully",
"problem": { ... }
}Error Responses:
401- Unauthorized request403- Only admin can update problems404- Problem not found400- Validation errors500- Error while updating problem
DELETE /problems/delete-problem/:id
Auth Required: Yes (verifyJWT)
Admin Required: Yes (checkAdmin)
URL Params:
id(string): Problem MongoDB ID
Response (200):
{
"success": true,
"message": "Problem deleted successfully"
}Error Responses:
401- Unauthorized request403- Only admin can delete problems404- Problem not found500- Error while deleting problem
GET /problems/get-solved-problems
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"success": true,
"message": "Solved problems fetched successfully",
"solvedProblems": [
{
"_id": "problemsolved_id",
"problem": "problem_id",
"solvedBy": "user_id",
"solvedAt": "2025-03-09T10:30:00Z"
}
]
}Error Responses:
401- Unauthorized request500- Error fetching solved problems
GET /submission/get-all-submissions
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"success": true,
"message": "Submissions fetched successfully",
"submissions": [
{
"_id": "submission_id",
"problem": "problem_id",
"submitBy": "user_id",
"sourceCode": "function twoSum(nums) { ... }",
"language": "javascript",
"status": "ACCEPTED",
"stdin": "2 3\n4 5",
"stdout": "[0,1]",
"stderr": null,
"memory": "45 KB",
"time": "0.05 s",
"submittedAt": "2025-03-09T10:30:00Z"
}
]
}Error Responses:
401- Unauthorized request500- Failed to fetch submissions
GET /submission/get-submission/:problemId
Auth Required: Yes (verifyJWT)
URL Params:
problemId(string): Problem MongoDB ID
Success Response (200):
{
"success": true,
"message": "Submissions for a problem fetched successfully",
"submissions": [...]
}Error Responses:
401- Unauthorized request500- Submissions for a problem Failed
GET /submission/get-submissions-counts/:problemId
Auth Required: Yes (verifyJWT)
URL Params:
problemId(string): Problem MongoDB ID
Success Response (200):
{
"success": true,
"message": "getAllTheSubmissionsForProblem fetched successfully",
"count": 42
}Error Responses:
401- Unauthorized request500- getAllTheSubmissionsForProblem Failed
POST /execute-code/
Auth Required: Yes (verifyJWT)
Request Body:
{
"source_code": "function twoSum(nums, target) { return [0,1]; }",
"language_id": 63,
"stdin": ["2 7 11 15\n9", "3 2 4\n6"],
"expected_outputs": ["0 1", "0 2"],
"problemId": "problem_mongo_id"
}Note: language_id maps from Judge0 API:
63- JavaScript71- Python54- C++
Success Response (200):
{
"success": true,
"message": "Code executed successfully",
"submission": {
"_id": "submission_id",
"problem": "problem_id",
"submitBy": "user_id",
"sourceCode": "...",
"language": "javascript",
"status": "ACCEPTED",
"detailedResults": [
{
"testCase": 1,
"passed": true,
"stdout": "0 1",
"expectedOutput": "0 1",
"stderr": null,
"status": "Accepted"
},
{
"testCase": 2,
"passed": true,
"stdout": "0 2",
"expectedOutput": "0 2",
"stderr": null,
"status": "Accepted"
}
]
}
}Error Responses:
401- Unauthorized request400- Invalid or Missing test cases500- Error executing code
External Service: Uses Judge0 API for code execution
GET /list/
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"success": true,
"message": "All Lists fetched successfully",
"allLists": [
{
"_id": "list_id",
"title": "Must Solve Array Problems",
"description": "Array problems from Easy to Medium",
"createdBy": "user_id",
"problemsInList": [
{
"_id": "problemsInList_id",
"problem": {
"_id": "problem_id",
"title": "Two Sum",
"difficulty": "Easy"
}
}
],
"createdAt": "2025-03-09T10:30:00Z"
}
]
}Error Responses:
401- Unauthorized request500- Failed to fetch All Lists
GET /list/:listId
Auth Required: Yes (verifyJWT)
URL Params:
listId(string): List MongoDB ID
Success Response (200):
{
"success": true,
"message": "A list fetched successfully",
"list": { ... }
}Error Responses:
401- Unauthorized request404- List not found500- Failed to fetch A List
POST /list/create-playlist
Auth Required: Yes (verifyJWT)
Request Body:
{
"title": "Array Problems",
"description": "All array-based DSA problems"
}Success Response (200):
{
"success": true,
"message": "List created Successfully",
"list": {
"_id": "list_id",
"title": "Array Problems",
"description": "All array-based DSA problems",
"createdBy": "user_id",
"problemsInList": [],
"createdAt": "2025-03-09T10:30:00Z"
}
}Error Responses:
401- Unauthorized request500- Failed to create List
POST /list/:listId/add-problem
Auth Required: Yes (verifyJWT)
URL Params:
listId(string): List MongoDB ID
Request Body:
{
"problemIds": ["problem_id_1", "problem_id_2", "problem_id_3"]
}Success Response (201):
{
"success": true,
"message": "Problems added to list successfully",
"problemsInList": [...]
}Error Responses:
401- Unauthorized request400- Invalid or missing problemId500- Failed to add problems to list
DELETE /list/:listId/remove-problem
Auth Required: Yes (verifyJWT)
URL Params:
listId(string): List MongoDB ID
Request Body:
{
"problemIds": ["problem_id_1", "problem_id_2"]
}Success Response (200):
{
"success": true,
"message": "Problems removed from list successfully"
}Error Responses:
401- Unauthorized request400- Invalid or missing problemId500- Failed to remove problems
DELETE /list/:listId
Auth Required: Yes (verifyJWT)
URL Params:
listId(string): List MongoDB ID
Success Response (200):
{
"success": true,
"message": "List deleted successfully"
}Error Responses:
401- Unauthorized request404- List not found500- Failed to delete list
POST /contest/create-manual
Auth Required: Yes (verifyJWT)
Request Body:
{
"title": "Weekly Challenge - March 2025",
"problemLinks": [
"https://leetcode.com/problems/two-sum/",
"https://leetcode.com/problems/reverse-string/",
"https://leetcode.com/problems/valid-parentheses/"
],
"duration": 120,
"questionCount": 3
}Validation Rules:
questionCount: Must be between 2-4problemLinks: Array length must equalquestionCount- All links must be LeetCode URLs containing "leetcode.com/problems/"
Success Response (201):
{
"success": true,
"message": "Contest started! Go to LeetCode and solve.",
"contest": {
"_id": "contest_id",
"title": "Weekly Challenge - March 2025",
"createdBy": "user_id",
"problems": [
{
"link": "https://leetcode.com/problems/two-sum/",
"titleSlug": "two-sum",
"title": "two sum",
"solved": false
},
{ ... }
],
"duration": 120,
"questionCount": 3,
"startTime": "2025-03-09T10:30:00Z",
"endTime": "2025-03-09T12:30:00Z",
"status": "active"
}
}Error Responses:
401- Unauthorized request400- User does not have leetcodeUsername linked400- All fields required400- Links count doesn't match questionCount400- Only leetcode links allowed400- Invalid question count (must be 2-4)500- Internal Server Error
Prerequisite: User must have leetcodeUsername set in their profile
POST /contest/end/:contestId
Auth Required: Yes (verifyJWT)
Validation: endContestResultValidation()
URL Params:
contestId(string): Contest MongoDB ID
Request Body: None (fetches from LeetCode API)
Success Response (200):
{
"success": true,
"message": "Contest ended successfully",
"results": {
"totalQuestions": 3,
"solvedCount": 2,
"score": 66.67,
"problems": [
{
"titleSlug": "two-sum",
"solved": true,
"detail": "Solved at 2025-03-09T10:45:00Z"
},
{
"titleSlug": "reverse-string",
"solved": true,
"detail": "Solved at 2025-03-09T11:00:00Z"
},
{
"titleSlug": "valid-parentheses",
"solved": false,
"detail": "Not solved"
}
]
}
}Error Responses:
401- Unauthorized request404- Contest not found400- Contest already ended400- User must link LeetCode username first500- Internal Server Error
Verification Logic:
- Checks if problems were solved within contest time window
- Validates against LeetCode API
- Marks contest status as "completed"
GET /contest/all-contest
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"success": true,
"message": "All contests fetched successfully",
"contests": [
{
"_id": "contest_id",
"title": "Weekly Challenge",
"status": "active|completed",
"startTime": "2025-03-09T10:30:00Z",
"endTime": "2025-03-09T12:30:00Z",
"questionCount": 3,
"problems": [...]
}
]
}Error Responses:
401- Unauthorized request500- Failed to fetch contests
POST /contest/generate-weekly
Auth Required: Yes (verifyJWT)
Request Body: None
Success Response (201):
{
"success": true,
"message": "Weekly contest generated successfully",
"contest": {
"_id": "contest_id",
"title": "Weekly Random Contest",
"problems": [4 random problems],
"status": "active"
}
}Error Responses:
401- Unauthorized request500- Failed to generate weekly contest
Note: Selects 4 random problems from the database
POST /chat/create-group
Auth Required: Yes (verifyJWT)
Validation: createGroupChatValidation()
Request Body:
{
"name": "DSA Study Group",
"members": ["user_id_1", "user_id_2", "user_id_3"]
}Success Response (201):
{
"success": true,
"message": "Group created successfully",
"data": {
"_id": "chat_id",
"name": "DSA Study Group",
"groupChat": true,
"createdBy": "current_user_id",
"members": ["current_user_id", "user_id_1", "user_id_2", "user_id_3"],
"createdAt": "2025-03-09T10:30:00Z"
}
}Error Responses:
401- Unauthorized request400- Validation failed500- Internal server error while creating group
GET /chat/my-chats
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"message": "Chats fetched successfully",
"chats": [
{
"_id": "chat_id",
"name": "John Doe", // For 1-on-1, shows other person's name
"groupChat": false,
"members": ["friend_user_id"]
},
{
"_id": "group_chat_id",
"name": "DSA Study Group",
"groupChat": true,
"members": ["user_id_1", "user_id_2", "user_id_3"]
}
]
}Error Responses:
401- Unauthorized request500- Error while fetching all the Chats
GET /chat/my-groups
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"success": true,
"message": "Groups fetched succesfully",
"groups": [
{
"_id": "group_chat_id",
"name": "DSA Study Group",
"members": [
{
"_id": "user_id_1",
"fullname": "John Doe"
},
{
"_id": "user_id_2",
"fullname": "Jane Smith"
}
],
"groupChat": true
}
]
}Error Responses:
401- Unauthorized request500- Error while fetching all the groups
PUT /chat/add-members
Auth Required: Yes (verifyJWT)
Validation: addMembersValidation()
Request Body:
{
"chatId": "group_chat_id",
"members": ["new_user_id_1", "new_user_id_2"]
}Success Response (200):
{
"success": true,
"message": "Members added successfully",
"chat": {
"_id": "group_chat_id",
"name": "DSA Study Group",
"members": [..., "new_user_id_1", "new_user_id_2"]
}
}Error Responses:
401- Unauthorized request404- Chat not found403- Only admin can add members400- Members already added500- Error adding members
Authorization: Only group creator can add members
DELETE /chat/remove-member
Auth Required: Yes (verifyJWT)
Validation: removeMemberValidation()
Request Body:
{
"chatId": "group_chat_id",
"memberId": "user_id_to_remove"
}Success Response (200):
{
"success": true,
"message": "Member removed successfully"
}Error Responses:
401- Unauthorized request404- Chat not found403- Only admin can remove members500- Error removing member
DELETE /chat/exit-group/:id
Auth Required: Yes (verifyJWT)
Validation: chatIdValidation()
URL Params:
id(string): Chat MongoDB ID
Success Response (200):
{
"success": true,
"message": "Exited group successfully"
}Error Responses:
401- Unauthorized request404- Chat not found500- Error exiting group
POST /chat/send-attachment
Auth Required: Yes (verifyJWT)
Content-Type: multipart/form-data
Validation: sendAttachmentValidation()
Request:
- Files:
files(up to 5 files) - Body Fields:
{ "chatId": "chat_id", "description": "Check out this solution" }
Success Response (201):
{
"success": true,
"message": "Message sent successfully",
"message": {
"_id": "message_id",
"chat": "chat_id",
"sender": "user_id",
"attachments": [
{
"public_id": "cloudinary_id",
"url": "https://cloudinary_url",
"type": "image|document|code"
}
],
"description": "Check out this solution",
"createdAt": "2025-03-09T10:30:00Z"
}
}Error Responses:
401- Unauthorized request400- Invalid chat or description400- File upload failed500- Error sending message
Limits: Max 5 files per message
GET /chat/message/:id
Auth Required: Yes (verifyJWT)
Validation: chatIdValidation()
URL Params:
id(string): Chat MongoDB ID
Query Params:
page(optional): Pagination page numberlimit(optional): Messages per page
Success Response (200):
{
"success": true,
"message": "Messages fetched successfully",
"messages": [
{
"_id": "message_id",
"chat": "chat_id",
"sender": {
"_id": "user_id",
"fullname": "John Doe"
},
"content": "Hello everyone!",
"attachments": [],
"createdAt": "2025-03-09T10:30:00Z"
}
]
}Error Responses:
401- Unauthorized request404- Chat not found500- Error fetching messages
GET /chat/:id
Auth Required: Yes (verifyJWT)
Validation: chatIdValidation()
URL Params:
id(string): Chat MongoDB ID
Success Response (200):
{
"success": true,
"message": "Chat details fetched successfully",
"chat": {
"_id": "chat_id",
"name": "DSA Study Group",
"groupChat": true,
"createdBy": "admin_user_id",
"members": [...],
"createdAt": "2025-03-09T10:30:00Z"
}
}Error Responses:
401- Unauthorized request404- Chat not found500- Error fetching chat details
PUT /chat/:id
Auth Required: Yes (verifyJWT)
Validation: renameChatValidation()
URL Params:
id(string): Chat MongoDB ID
Request Body:
{
"name": "New Group Name"
}Success Response (200):
{
"success": true,
"message": "Chat renamed successfully",
"chat": {
"_id": "chat_id",
"name": "New Group Name"
}
}Error Responses:
401- Unauthorized request403- Only admin can rename404- Chat not found500- Error renaming chat
DELETE /chat/:id
Auth Required: Yes (verifyJWT)
Validation: chatIdValidation()
URL Params:
id(string): Chat MongoDB ID
Success Response (200):
{
"success": true,
"message": "Chat deleted successfully"
}Error Responses:
401- Unauthorized request404- Chat not found500- Error deleting chat
GET /friend/search
Auth Required: Yes (verifyJWT)
Query Params:
fullname(string): Name to search for
Success Response (200):
{
"success": true,
"users": [
{
"_id": "user_id",
"fullname": "John Doe",
"avatar": "https://avatar_url"
},
{
"_id": "user_id_2",
"fullname": "John Smith",
"avatar": "https://avatar_url"
}
]
}Error Responses:
401- Unauthorized request500- Error searching users
Note: Excludes already-friends and the current user
PUT /friend/send-request
Auth Required: Yes (verifyJWT)
Validation: sendRequestValidation()
Request Body:
{
"receiverId": "target_user_id"
}Success Response (200):
{
"success": true,
"message": "request sent successfully",
"request": {
"_id": "request_id",
"sender": "current_user_id",
"receiver": "target_user_id",
"createdAt": "2025-03-09T10:30:00Z"
}
}Error Responses:
401- Unauthorized request400- Request already sent500- Error sending request
Duplicate Prevention: Checks both directions to avoid duplicate requests
PUT /friend/accept-request
Auth Required: Yes (verifyJWT)
Validation: acceptRequestValidation()
Request Body:
{
"requestId": "request_id",
"accept": true
}Success Response (200):
- If
accept: true:
{
"success": true,
"message": "Friend added successfully",
"chat": {
"_id": "new_chat_id",
"name": "Sender Name-Receiver Name",
"members": ["sender_id", "receiver_id"],
"groupChat": false
}
}- If
accept: false:
{
"success": true,
"message": "request rejected"
}Error Responses:
401- Unauthorized request404- Request not found401- You are not authorized to accept this request500- Error processing request
Side Effects:
- On accept: Creates a 1-on-1 chat between both users
- Deletes the friend request
GET /friend/notification
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"success": true,
"message": "Notifications fetched successfully",
"requests": [
{
"_id": "request_id",
"sender": {
"_id": "sender_id",
"fullname": "John Doe",
"avatar": "https://avatar_url"
},
"receiver": "current_user_id",
"createdAt": "2025-03-09T10:30:00Z"
}
]
}Error Responses:
401- Unauthorized request500- Error fetching notifications
GET /friend/my-friends
Auth Required: Yes (verifyJWT)
Success Response (200):
{
"success": true,
"message": "Friends fetched successfully",
"friends": [
{
"_id": "friend_id",
"fullname": "John Doe",
"avatar": "https://avatar_url",
"email": "john@example.com"
}
]
}Error Responses:
401- Unauthorized request500- Error fetching friends
{
_id: ObjectId,
username: String (3-20 chars, lowercase, unique),
email: String (unique, lowercase),
password: String (8+ chars, hashed),
fullname: String (3+ chars),
role: String (ADMIN | STUDENT),
avatar: {
public_id: String (Cloudinary),
url: String (image URL)
},
isVerified: Boolean,
refreshToken: String (JWT),
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
title: String,
description: String,
difficulty: String (Easy|Medium|Hard),
tags: [String],
constraints: String,
hints: [String],
examples: [{ input, output, explanation }],
testcases: [{ input, output }],
codeSnippets: { javascript, python, cpp },
referenceSolution: { javascript, python, cpp },
createdBy: ObjectId (User ID),
createdAt: Date
}{
_id: ObjectId,
submitBy: ObjectId (User ID),
problem: ObjectId (Problem ID),
sourceCode: String,
language: String (javascript|python|cpp),
status: String (ACCEPTED|WRONG_ANSWER|TIME_LIMIT|RUNTIME_ERROR),
stdin: String,
stdout: String (JSON),
stderr: String (JSON),
memory: String (JSON),
time: String (JSON),
submittedAt: Date
}{
_id: ObjectId,
name: String,
groupChat: Boolean,
createdBy: ObjectId (User ID),
members: [ObjectId] (User IDs),
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
chat: ObjectId (Chat ID),
sender: ObjectId (User ID),
content: String,
attachments: [{
public_id: String,
url: String,
type: String
}],
createdAt: Date
}{
_id: ObjectId,
title: String,
description: String,
createdBy: ObjectId (User ID),
problemsInList: [ObjectId],
createdAt: Date
}{
_id: ObjectId,
title: String,
createdBy: ObjectId (User ID),
problems: [{
link: String (LeetCode URL),
titleSlug: String,
title: String,
solved: Boolean
}],
duration: Number (minutes),
questionCount: Number,
startTime: Date,
endTime: Date,
status: String (active|completed),
createdAt: Date
}{
"message": "Error description",
"success": false,
"error": "Optional detailed error"
}200- Success (GET, PUT)201- Created (POST)400- Bad Request (validation errors, invalid data)401- Unauthorized (missing/invalid token)403- Forbidden (insufficient permissions/role)404- Not Found (resource doesn't exist)500- Internal Server Error (server-side error)
- "Unauthorized request" β No token provided
- "Invalid access token" β Token validation failed
- "Unauthorized request" β Token expired
- "Only admin can..." β User role doesn't have permission
- "User not found" β User doesn't exist
- "Invalid user credentials" β Wrong password/email
Location: /chat/send-attachment endpoint
Issue: The endpoint uses sendAttachmentValidation without calling validate middleware
Recommendation:
// Current
chatRouter.post("/send-attachment", verifyJWT, sendAttachmentValidation, validate, upload.array("files", 5), sendAttachment);
// Should be
chatRouter.post("/send-attachment", verifyJWT, sendAttachmentValidation(), validate, upload.array("files", 5), sendAttachment);
// Note: sendAttachmentValidation() should return a middleware functionLocation: problem.routes.js
Issue: Last route is missing semicolon
Recommendation: Add semicolon:
problemRouter.get("/get-solved-problems", verifyJWT, getAllProblemsSolvedByUser);Location: Contest controller - endContestResult
Issue: Function fetchLeetCodeSubmissions is commented out, endpoint will fail
Recommendation: Implement the LeetCode API integration:
import { fetchLeetCodeSubmissions } from "../utils/leetcode.js";
// Uncomment and test thoroughlyLocation: List controller - addProblemInList
Issue: Can add same problem multiple times to a list
Recommendation:
const existingProblems = await ProblemsInList.find({
list: listId,
problem: { $in: problemIds }
});
const newProblemIds = problemIds.filter(id =>
!existingProblems.some(p => p.problem.toString() === id)
);Issue: Some endpoints return success: true, others don't
Recommendation: Standardize all responses:
// Always include success field
{
success: true|false,
message: "...",
data: {...} // Use 'data' for main response payload
}Issue: No rate limiting on critical endpoints (register, login, execute code)
Recommendation: Implement using express-rate-limit:
import rateLimit from 'express-rate-limit';
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5 // 5 requests per window
});
authRouter.post("/login", loginLimiter, loginValidation(), validate, loginUser);Issue: User inputs not sanitized against injection attacks
Recommendation: Add express-validator sanitization:
import { body, validationResult } from 'express-validator';
const registrationValidation = () => [
body('email').isEmail().normalizeEmail(),
body('username').trim().toLowerCase().escape(),
body('fullname').trim().escape(),
];Issue: getAllProblems and getMyChats return all records
Recommendation: Add pagination:
const page = req.query.page || 1;
const limit = req.query.limit || 10;
const skip = (page - 1) * limit;
const problems = await Problem.find()
.skip(skip)
.limit(limit);- Some use kebab-case:
/get-all-problems - Some use snake_case:
/get_submission - Some use camelCase:
/createProblem
Recommendation: Standardize to kebab-case for all routes
Issue: No @deprecated, @since, @changelog markers
Recommendation: Add JSDoc comments to all controllers
Issue: Missing request/response logging
Recommendation: Implement Morgan logger:
import morgan from 'morgan';
app.use(morgan('combined'));Issue: No "accept" status checking before blocking/unfriending
Recommendation: Add friendship status model with states: PENDING|ACCEPTED|BLOCKED
- Missing: Update contest details
- Missing: Get specific contest details
- Missing: Leaderboard endpoint Recommendation: Add endpoints:
PUT /contest/:id - Update contest
GET /contest/:id - Get contest details
GET /contest/:id/leaderboard - Get results
Issue: Test cases not validated for format consistency
Recommendation: Add validation in problem creation
Issue: Hard deletes for problems (might break submissions references)
Recommendation: Implement soft delete with isDeleted flag
- Set
secure: truein all cookie options (HTTPS required) - Change CORS origin from
localhost:5173to actual frontend domain - Implement rate limiting on all auth endpoints
- Add input sanitization and validation
- Set up proper error logging (e.g., Sentry)
- Add request logging (Morgan)
- Implement data backup strategy
- Set up monitoring and alerting
- Configure environment variables properly
- Add request ID tracking for debugging
- Implement comprehensive API versioning strategy
- Add API documentation (Swagger/OpenAPI)
// Register
POST /auth/register β Get user + tokens
// Login
POST /auth/login β Get user + accessToken + refreshToken
// Check Auth Status
GET /auth/check β Returns current user
// Logout
POST /auth/logout β Clears tokens// Get problems
GET /problems/get-All-problems
// Get specific problem
GET /problems/get-problem/:id
// Execute code
POST /execute-code
// View submissions
GET /submission/get-all-submissions
GET /submission/get-submission/:problemId// Search user
GET /friend/search?fullname=john
// Send friend request
PUT /friend/send-request
// Accept request
PUT /friend/accept-request
// Get notifications
GET /friend/notification
// Start chatting
POST /chat/create-group or use 1-on-1 chat# Database
MONGODB_URI=mongodb://localhost:27017/leetlab
# JWT
ACCESS_TOKEN_SECRET=your_access_secret_key
REFRESH_TOKEN_SECRET=your_refresh_secret_key
# Cloudinary (for file uploads)
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# Judge0 (for code execution)
JUDGE0_API_HOST=your_judge0_host
JUDGE0_API_KEY=your_judge0_key
# LeetCode (for contest verification)
LEETCODE_API_ENDPOINT=https://leetcode.com/graphql
# Frontend
FRONTEND_URL=http://localhost:5173
# Server
PORT=5000- Fix Critical Issues: Items marked as π΄
- Add Missing Endpoints: Contest details, leaderboard
- Implement Rate Limiting: Protect against abuse
- Add Swagger/OpenAPI: Auto-generate interactive docs
- Add Unit Tests: Increase code coverage
- Performance Optimization: Add caching, database indexing
- Security Audit: Run OWASP ZAP scan
Last Updated: March 9, 2025
Status: Production Ready (with recommended fixes)