{"id":27429597,"url":"https://github.com/banesito/gjejpune-backend","last_synced_at":"2025-04-14T14:28:25.612Z","repository":{"id":280208573,"uuid":"915818609","full_name":"banesito/GjejPune-Backend","owner":"banesito","description":"A job board backend build with Express Js and a Mongo DB database with Mongose, Email Verification, Role based auth and much more.","archived":false,"fork":false,"pushed_at":"2025-03-02T00:35:24.000Z","size":105,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T13:45:38.234Z","etag":null,"topics":["express-js","javascript","job-board","jwt","mongodb","mongoose","rest-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/banesito.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-12T21:57:35.000Z","updated_at":"2025-03-02T00:35:27.000Z","dependencies_parsed_at":"2025-03-05T04:15:29.074Z","dependency_job_id":null,"html_url":"https://github.com/banesito/GjejPune-Backend","commit_stats":null,"previous_names":["b4n3y/gjejpune-backend","banesito/gjejpune-backend"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banesito%2FGjejPune-Backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banesito%2FGjejPune-Backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banesito%2FGjejPune-Backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/banesito%2FGjejPune-Backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/banesito","download_url":"https://codeload.github.com/banesito/GjejPune-Backend/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248896439,"owners_count":21179430,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["express-js","javascript","job-board","jwt","mongodb","mongoose","rest-api"],"created_at":"2025-04-14T14:28:24.793Z","updated_at":"2025-04-14T14:28:25.586Z","avatar_url":"https://github.com/banesito.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Job Portal API\n\nA job board backend build with Express Js and a Mongo DB database with Mongose, Email Verification, Role based auth rate limiting, and advanced security features. It also has support for s3 object storage like aws s3 buckets and digital ocean spaces\nBuild in messaging for users who have applied and businesses\n## Features\n\n### Authentication \u0026 Security\n- JWT-based authentication\n- Email verification system\n- Password reset functionality\n- Rate limiting for sensitive endpoints\n- Domain-restricted email registration (gmail.com, icloud.com, outlook.com only)\n- MongoDB-based rate limiting for email operations\n\n### User Management\n- User registration with email verification\n- Business registration with approval system\n- Profile management\n- Interest-based job notifications (max 3 interests)\n- Email verification required for all operations\n\n### Job Management\n- Job posting and management\n- Job applications with status tracking\n- Job categories with validation\n- Application tracking\n- Approval system for jobs\n\n### Notifications\n- Email notifications for verification\n- Password reset emails\n- Job application notifications\n- New job notifications based on interests\n\n## API Endpoints Documentation\n\n### Authentication\n\n#### Register User\n```http\nPOST /v1/auth/user/register\n```\nRequest:\n```json\n{\n  \"email\": \"user@gmail.com\",\n  \"password\": \"StrongPass1!\",\n  \"username\": \"johndoe\",\n  \"firstName\": \"John\",\n  \"lastName\": \"Doe\",\n  \"phoneNumber\": \"+1234567890\",\n  \"interests\": [\"65d4a5e7c1f1c8c1a5f7b3d2\"]\n}\n```\nResponse (201):\n```json\n{\n  \"message\": \"Registration successful. Please check your email for verification.\",\n  \"userId\": \"65d4a5e7c1f1c8c1a5f7b3d1\"\n}\n```\nError Responses:\n```json\n{\n  \"error\": \"Email, username, or phone number already registered\"\n}\n```\n```json\n{\n  \"error\": \"Interest(s) with ID(s) 65d4a5e7c1f1c8c1a5f7b3d2 do not exist\"\n}\n```\n\n#### Register Business\n```http\nPOST /v1/auth/business/register\n```\nRequest:\n```json\n{\n  \"email\": \"business@gmail.com\",\n  \"password\": \"StrongPass1!\",\n  \"businessName\": \"Tech Corp\",\n  \"businessType\": \"Technology\",\n  \"contactPerson\": {\n    \"name\": \"Jane Smith\",\n    \"phoneNumber\": \"+1234567891\",\n    \"position\": \"HR Manager\"\n  },\n  \"address\": {\n    \"street\": \"123 Tech St\",\n    \"city\": \"San Francisco\",\n    \"state\": \"CA\",\n    \"zipCode\": \"94105\",\n    \"country\": \"USA\"\n  }\n}\n```\nResponse (201):\n```json\n{\n  \"token\": \"eyJhbG...\",\n  \"type\": \"business\",\n  \"profile\": {\n    \"id\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n    \"businessName\": \"Tech Corp\",\n    \"email\": \"business@gmail.com\",\n    \"isEmailVerified\": false,\n    \"approved\": false\n  },\n  \"expiresIn\": \"7 days\"\n}\n```\n\n#### User Login\n```http\nPOST /v1/auth/user/login\n```\nRequest:\n```json\n{\n  \"email\": \"user@gmail.com\",\n  \"password\": \"StrongPass1!\"\n}\n```\nResponse (200):\n```json\n{\n  \"token\": \"eyJhbG...\",\n  \"user\": {\n    \"id\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n    \"email\": \"user@gmail.com\",\n    \"username\": \"johndoe\",\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"isEmailVerified\": true\n  },\n  \"expiresIn\": \"7 days\"\n}\n```\nError Responses:\n```json\n{\n  \"error\": \"Invalid credentials\"\n}\n```\n```json\n{\n  \"error\": \"Email not verified\",\n  \"message\": \"Please verify your email address before logging in. Check your inbox for the verification link.\"\n}\n```\n\n#### Business Login\n```http\nPOST /v1/auth/business/login\n```\nRequest:\n```json\n{\n  \"email\": \"business@gmail.com\",\n  \"password\": \"StrongPass1!\"\n}\n```\nResponse (200):\n```json\n{\n  \"token\": \"eyJhbG...\",\n  \"type\": \"business\",\n  \"profile\": {\n    \"id\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n    \"businessName\": \"Tech Corp\",\n    \"email\": \"business@gmail.com\",\n    \"isEmailVerified\": true,\n    \"approved\": true\n  },\n  \"expiresIn\": \"7 days\"\n}\n```\nError Responses:\n```json\n{\n  \"error\": \"Invalid credentials\"\n}\n```\n```json\n{\n  \"error\": \"Email not verified\",\n  \"message\": \"Please verify your email address before logging in. Check your inbox for the verification link.\"\n}\n```\n```json\n{\n  \"error\": \"Account pending approval\",\n  \"message\": \"Your business account is pending approval. Please wait for administrator approval.\"\n}\n```\n\n### Email Verification\n\n#### Verify Email\n```http\nGET /v1/auth/verify-email/:token\n```\nResponse (200):\n```json\n{\n  \"message\": \"Email verified successfully\"\n}\n```\n\n#### Resend Verification Email\n```http\nPOST /v1/auth/resend-verification\n```\nRequest:\n```json\n{\n  \"email\": \"user@gmail.com\"\n}\n```\nResponse (200):\n```json\n{\n  \"message\": \"Verification email sent successfully\"\n}\n```\nError Response (429):\n```json\n{\n  \"error\": \"Too many attempts. Please try again in 1 hour.\"\n}\n```\n\n#### Request Password Reset\n```http\nPOST /v1/auth/forgot-password\n```\nRequest:\n```json\n{\n  \"email\": \"user@gmail.com\"\n}\n```\nResponse (200):\n```json\n{\n  \"message\": \"Password reset email sent successfully\"\n}\n```\n\n#### Reset Password\n```http\nPOST /v1/auth/reset-password/:token\n```\nRequest:\n```json\n{\n  \"password\": \"NewStrongPass1!\"\n}\n```\nResponse (200):\n```json\n{\n  \"message\": \"Password reset successfully\"\n}\n```\n\n### Profile Management\n\n#### Get User Profile\n```http\nGET /v1/auth/user/profile\n```\nResponse (200):\n```json\n{\n  \"id\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n  \"email\": \"user@gmail.com\",\n  \"username\": \"johndoe\",\n  \"firstName\": \"John\",\n  \"lastName\": \"Doe\",\n  \"phoneNumber\": \"+1234567890\",\n  \"interests\": [\n    {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d2\",\n      \"name\": \"Programming\"\n    }\n  ],\n  \"isEmailVerified\": true\n}\n```\n\n#### Update User Profile\n```http\nPATCH /v1/auth/user/profile\n```\nRequest:\n```json\n{\n  \"firstName\": \"John\",\n  \"lastName\": \"Smith\",\n  \"phoneNumber\": \"+1234567890\",\n  \"interests\": [\"65d4a5e7c1f1c8c1a5f7b3d2\"]\n}\n```\nResponse (200):\n```json\n{\n  \"id\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n  \"email\": \"user@gmail.com\",\n  \"username\": \"johndoe\",\n  \"firstName\": \"John\",\n  \"lastName\": \"Smith\",\n  \"phoneNumber\": \"+1234567890\",\n  \"interests\": [\n    {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d2\",\n      \"name\": \"Programming\"\n    }\n  ]\n}\n```\n\n### Jobs\n\n#### Create Job (Business Only)\n```http\nPOST /v1/jobs\n```\nRequest:\n```json\n{\n  \"title\": \"Senior Developer\",\n  \"description\": \"We are looking for a senior developer...\",\n  \"requirements\": [\"5+ years experience\", \"Node.js\", \"MongoDB\"],\n  \"salary\": \"$120,000 - $150,000\",\n  \"category\": \"65d4a5e7c1f1c8c1a5f7b3d2\"\n}\n```\nResponse (201):\n```json\n{\n  \"id\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n  \"title\": \"Senior Developer\",\n  \"description\": \"We are looking for a senior developer...\",\n  \"requirements\": [\"5+ years experience\", \"Node.js\", \"MongoDB\"],\n  \"salary\": \"$120,000 - $150,000\",\n  \"category\": \"65d4a5e7c1f1c8c1a5f7b3d2\",\n  \"businessId\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n  \"approved\": false,\n  \"createdAt\": \"2024-02-20T10:00:00.000Z\"\n}\n```\n\n#### Get Jobs (Public)\n```http\nGET /v1/jobs?page=1\u0026search=developer\n```\nResponse (200):\n```json\n{\n  \"jobs\": [{\n    \"id\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n    \"title\": \"Senior Developer\",\n    \"description\": \"We are looking for a senior developer...\",\n    \"requirements\": [\"5+ years experience\", \"Node.js\", \"MongoDB\"],\n    \"salary\": \"$120,000 - $150,000\",\n    \"businessId\": {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n      \"businessName\": \"Tech Corp\"\n    }\n  }],\n  \"pagination\": {\n    \"currentPage\": 1,\n    \"totalPages\": 5,\n    \"totalJobs\": 100,\n    \"perPage\": 30,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\n```\n\n#### Apply for Job\n```http\nPOST /v1/jobs/:id/apply\n```\nResponse (201):\n```json\n{\n  \"message\": \"Application submitted successfully\",\n  \"application\": {\n    \"id\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n    \"jobId\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n    \"userId\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n    \"status\": \"pending\",\n    \"applicantDetails\": {\n      \"fullName\": \"John Smith\",\n      \"email\": \"user@gmail.com\",\n      \"phoneNumber\": \"+1234567890\"\n    }\n  }\n}\n```\n\n### Job Categories\n\n#### Get Categories\n```http\nGET /v1/jobs/categories\n```\nResponse (200):\n```json\n{\n  \"categories\": [\n    {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d2\",\n      \"name\": \"Programming\",\n      \"slug\": \"programming\",\n      \"description\": \"Software development and programming roles\"\n    }\n  ]\n}\n```\n\n### Notifications\n\n#### Get Notifications\n```http\nGET /v1/notifications?page=1\n```\nResponse (200):\n```json\n{\n  \"notifications\": [{\n    \"id\": \"65d4a5e7c1f1c8c1a5f7b3d6\",\n    \"type\": \"JOB_APPLICATION_RECEIVED\",\n    \"title\": \"New Job Application\",\n    \"message\": \"New application received for \\\"Senior Developer\\\"\",\n    \"read\": false,\n    \"createdAt\": \"2024-02-20T10:00:00.000Z\",\n    \"metadata\": {\n      \"jobId\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n      \"jobTitle\": \"Senior Developer\",\n      \"applicationId\": \"65d4a5e7c1f1c8c1a5f7b3d5\"\n    }\n  }],\n  \"unreadCount\": 1,\n  \"pagination\": {\n    \"currentPage\": 1,\n    \"totalPages\": 1,\n    \"totalNotifications\": 1,\n    \"perPage\": 30,\n    \"hasNextPage\": false,\n    \"hasPrevPage\": false\n  }\n}\n```\n\n### Job Applications\n\n#### Get My Applications (User)\n```http\nGET /v1/jobs/my-applications\n```\nResponse (200):\n```json\n{\n  \"applications\": [\n    {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n      \"jobId\": {\n        \"id\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n        \"title\": \"Senior Developer\",\n        \"description\": \"We are looking for a senior developer...\",\n        \"salary\": \"$120,000 - $150,000\"\n      },\n      \"businessId\": {\n        \"id\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n        \"businessName\": \"Tech Corp\"\n      },\n      \"status\": \"pending\",\n      \"createdAt\": \"2024-02-20T10:00:00.000Z\"\n    }\n  ],\n  \"pagination\": {\n    \"currentPage\": 1,\n    \"totalPages\": 5,\n    \"totalApplications\": 100,\n    \"perPage\": 30,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\n```\n\n#### Get Job Applications (Business)\n```http\nGET /v1/jobs/:id/applications\n```\nResponse (200):\n```json\n{\n  \"applications\": [\n    {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n      \"jobId\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n      \"status\": \"pending\",\n      \"applicantDetails\": {\n        \"fullName\": \"John Smith\",\n        \"email\": \"user@gmail.com\",\n        \"phoneNumber\": \"+1234567890\"\n      }\n    }\n  ],\n  \"pagination\": {\n    \"currentPage\": 1,\n    \"totalPages\": 3,\n    \"totalApplications\": 75,\n    \"perPage\": 30,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\nError Responses:\n```json\n{\n  \"error\": \"Job not found or unauthorized\"\n}\n```\n```json\n{\n  \"error\": \"Only businesses can perform this action\"\n}\n```\n\n#### Update Application Status (Business)\n```http\nPATCH /v1/jobs/:jobId/applications/:applicationId\n```\nRequest:\n```json\n{\n  \"status\": \"accepted\" // or \"rejected\", \"reviewed\", \"pending\"\n}\n```\nResponse (200):\n```json\n{\n  \"id\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n  \"jobId\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n  \"status\": \"accepted\",\n  \"applicantDetails\": {\n    \"fullName\": \"John Smith\",\n    \"email\": \"user@gmail.com\",\n    \"phoneNumber\": \"+1234567890\"\n  },\n  \"updatedAt\": \"2024-02-20T10:30:00.000Z\"\n}\n```\nError Responses:\n```json\n{\n  \"error\": \"Invalid status\"\n}\n```\n```json\n{\n  \"error\": \"Application not found or unauthorized\"\n}\n```\n\n### Messages\n\n#### Get Conversations List\n```http\nGET /v1/messages/conversations?page=1\n```\nResponse (200):\n```json\n{\n  \"conversations\": [\n    {\n      \"application\": {\n        \"id\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n        \"status\": \"pending\",\n        \"user\": {\n          \"id\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n          \"name\": \"John Doe\"\n        },\n        \"job\": {\n          \"id\": \"65d4a5e7c1f1c8c1a5f7b3d4\",\n          \"title\": \"Senior Developer\",\n          \"business\": {\n            \"id\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n            \"name\": \"Tech Corp\"\n          }\n        }\n      },\n      \"unreadCount\": 2,\n      \"lastMessage\": {\n        \"content\": \"Thank you for your interest in the position\",\n        \"createdAt\": \"2024-02-20T10:30:00.000Z\"\n      },\n      \"updatedAt\": \"2024-02-20T10:30:00.000Z\"\n    }\n  ],\n  \"pagination\": {\n    \"currentPage\": 1,\n    \"totalPages\": 5,\n    \"totalConversations\": 100,\n    \"perPage\": 30,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\n```\n\n#### Get Messages for a Conversation\n```http\nGET /v1/messages/:applicationId?page=1\n```\nResponse (200):\n```json\n{\n  \"messages\": [\n    {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d6\",\n      \"sender\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n      \"senderModel\": \"User\",\n      \"recipient\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n      \"recipientModel\": \"Business\",\n      \"jobApplication\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n      \"content\": \"I'm very interested in learning more about the position\",\n      \"read\": true,\n      \"createdAt\": \"2024-02-20T10:00:00.000Z\"\n    },\n    {\n      \"id\": \"65d4a5e7c1f1c8c1a5f7b3d7\",\n      \"sender\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n      \"senderModel\": \"Business\",\n      \"recipient\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n      \"recipientModel\": \"User\",\n      \"jobApplication\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n      \"content\": \"Thank you for your interest in the position\",\n      \"read\": false,\n      \"createdAt\": \"2024-02-20T10:30:00.000Z\"\n    }\n  ],\n  \"pagination\": {\n    \"currentPage\": 1,\n    \"totalPages\": 3,\n    \"totalMessages\": 75,\n    \"perPage\": 30,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\nError Responses:\n```json\n{\n  \"error\": \"Job application not found\"\n}\n```\n```json\n{\n  \"error\": \"You do not have access to this conversation\"\n}\n```\n\n#### Send Message\n```http\nPOST /v1/messages/:applicationId\n```\nRequest:\n```json\n{\n  \"content\": \"I'm very interested in learning more about the position\"\n}\n```\nResponse (201):\n```json\n{\n  \"id\": \"65d4a5e7c1f1c8c1a5f7b3d6\",\n  \"sender\": \"65d4a5e7c1f1c8c1a5f7b3d1\",\n  \"senderModel\": \"User\",\n  \"recipient\": \"65d4a5e7c1f1c8c1a5f7b3d3\",\n  \"recipientModel\": \"Business\",\n  \"jobApplication\": \"65d4a5e7c1f1c8c1a5f7b3d5\",\n  \"content\": \"I'm very interested in learning more about the position\",\n  \"read\": false,\n  \"createdAt\": \"2024-02-20T10:00:00.000Z\"\n}\n```\nError Responses:\n```json\n{\n  \"error\": \"Message content is required\"\n}\n```\n```json\n{\n  \"error\": \"Message content cannot exceed 2000 characters\"\n}\n```\n```json\n{\n  \"error\": \"Job application not found\"\n}\n```\n```json\n{\n  \"error\": \"You do not have access to this conversation\"\n}\n```\n\n#### Get Unread Messages Count\n```http\nGET /v1/messages/unread/count\n```\nResponse (200):\n```json\n{\n  \"count\": 5\n}\n```\n\n### Message Features and Limitations\n\n1. **Access Control**:\n   - Users can only message businesses they've applied to\n   - Businesses can only message users who've applied to their jobs\n   - All messages are linked to specific job applications\n\n2. **Message Limitations**:\n   - Maximum message length: 2000 characters\n   - Messages are text-only\n   - Messages cannot be edited or deleted\n\n3. **Pagination**:\n   - 30 items per page for both conversations and messages\n   - Sorted by most recent first\n   - Includes total counts and page information\n\n4. **Real-time Features**:\n   - Messages are marked as read automatically when viewed\n   - Unread message count is available\n   - Last message preview in conversations list\n\n5. **Notifications**:\n   - Users receive notifications for new messages\n   - Notifications include relevant metadata (job title, sender info)\n   - Notifications are automatically created when messages are sent\n\n### Testing the Messages API\n\n1. **Prerequisites**:\n   - User account with at least one job application\n   - Business account with at least one received application\n   - Valid JWT token in Authorization header\n\n2. **Test Flow for User**:\n   ```bash\n   # 1. Get conversations list\n   curl -X GET 'http://localhost:3000/v1/messages/conversations' \\\n   -H 'Authorization: Bearer YOUR_TOKEN'\n\n   # 2. Get messages for a specific application\n   curl -X GET 'http://localhost:3000/v1/messages/APPLICATION_ID' \\\n   -H 'Authorization: Bearer YOUR_TOKEN'\n\n   # 3. Send a message\n   curl -X POST 'http://localhost:3000/v1/messages/APPLICATION_ID' \\\n   -H 'Authorization: Bearer YOUR_TOKEN' \\\n   -H 'Content-Type: application/json' \\\n   -d '{\"content\": \"Hello, I am interested in this position\"}'\n\n   # 4. Check unread messages count\n   curl -X GET 'http://localhost:3000/v1/messages/unread/count' \\\n   -H 'Authorization: Bearer YOUR_TOKEN'\n   ```\n\n3. **Test Flow for Business**:\n   ```bash\n   # 1. Get conversations list\n   curl -X GET 'http://localhost:3000/v1/messages/conversations' \\\n   -H 'Authorization: Bearer YOUR_TOKEN'\n\n   # 2. Get messages for a specific application\n   curl -X GET 'http://localhost:3000/v1/messages/APPLICATION_ID' \\\n   -H 'Authorization: Bearer YOUR_TOKEN'\n\n   # 3. Reply to an application\n   curl -X POST 'http://localhost:3000/v1/messages/APPLICATION_ID' \\\n   -H 'Authorization: Bearer YOUR_TOKEN' \\\n   -H 'Content-Type: application/json' \\\n   -d '{\"content\": \"Thank you for your interest. When would you be available for an interview?\"}'\n\n   # 4. Check unread messages count\n   curl -X GET 'http://localhost:3000/v1/messages/unread/count' \\\n   -H 'Authorization: Bearer YOUR_TOKEN'\n   ```\n\n## Rate Limiting\n\n### Email Operations\n- Verification emails: 3 attempts per email per hour\n- Password reset emails: 3 attempts per email per hour\n- Tracked in MongoDB with auto-expiration after 1 hour\n\n### Authentication\n- Login/Register: 5 requests per 15 minutes\n- General API: 100 requests per 15 minutes\n- Job applications: 10 per hour\n\n## Installation \u0026 Setup\n\n1. Clone the repository\n2. Install dependencies:\n```bash\nnpm install\n```\n\n3. Set up environment variables (copy .env.example to .env):\n```env\n# Core Configuration\nMONGODB_URI=your-mongodb-uri\nJWT_SECRET=your-jwt-secret\nPORT=3000\n\n# Rate Limiting\nRATE_LIMIT_WINDOW_MS=900000  # 15 minutes\nRATE_LIMIT_MAX_REQUESTS=400   # Maximum requests per window\n\n# Email Configuration\nSMTP_HOST=smtp.hostinger.com\nSMTP_PORT=465\nSMTP_USER=your-email\nSMTP_PASS=your-password\nSMTP_FROM=Your Name \u003cyour-email\u003e\n\n# Security Secrets\nEMAIL_VERIFICATION_SECRET=your-verification-secret\nPASSWORD_RESET_SECRET=your-reset-secret\n\n# Backend URL\nBACKEND_URL=https://your-api-domain.com\n```\n\n4. Start the server:\n```bash\nnpm run dev  # Development\nnpm start    # Production\n```\n\n## Security Features\n\n- All passwords are hashed using bcrypt\n- JWT tokens for authentication\n- Rate limiting on sensitive endpoints\n- Email domain restrictions\n- MongoDB-based rate limiting for email operations\n- Protected sensitive fields\n- Input sanitization\n- XSS protection\n- CORS configuration\n- Email verification required for all operations \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanesito%2Fgjejpune-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbanesito%2Fgjejpune-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbanesito%2Fgjejpune-backend/lists"}