/**
* @fileoverview Express.js server for user authentication and post management
* @description This server provides REST API endpoints for user registration, login, account deletion,
* and basic post management functionality. It uses MongoDB for data persistence and JWT for authentication.
* @author Your Name
* @version 1.0.0
*/
const express = require('express');
const cors = require('cors');
const { connectToMongoDB, insertPost, getAllPosts, registerUser, LoginUser, deleteaUser } = require('./mongodb/mongodb');
require('dotenv').config();
/**
* Express application instance
* @type {express.Application}
*/
const app = express();
/**
* Server port - defaults to 4000 if not specified in environment
* @type {number}
*/
const PORT = process.env.PORT || 4000;
app.use(cors());
app.use(express.json());
/**
* Initializes and starts the Express server
* @async
* @function startServer
* @description Connects to MongoDB database and starts the Express server.
* The server will only start if MongoDB connection is successful.
* @throws {Error} If MongoDB connection fails, the process will exit with code 1
* @returns {Promise<void>}
*/
const startServer = async () => {
try {
// Connect to MongoDB
await connectToMongoDB();
console.log('MongoDB connection established successfully');
/**
* POST /run-test - Test MongoDB connection
* @name TestConnection
* @route {POST} /run-test
* @description Tests the MongoDB connection and returns the result
* @returns {Object} 200 - Success response with connection result
* @returns {Object} 500 - Error response if connection fails
* @example
* // Request body: {} (empty)
* // Success response:
* {
* "success": true,
* "result": "Connection successful"
* }
*/
app.post('/run-test', async (req, res) => {
try {
const result = await connectToMongoDB();
res.status(200).json({ success: true, result });
} catch (err) {
console.error('Error running test:', err);
res.status(500).json({ success: false, error: err.toString() });
}
});
/**
* POST /add-post - Add a new post
* @name AddPost
* @route {POST} /add-post
* @description Adds a new post to the database
* @param {Object} req.body - Post data
* @param {string} req.body.title - Post title
* @param {string} req.body.content - Post content
* @param {string} req.body.author - Post author
* @returns {Object} 200 - Success response with post creation result
* @returns {Object} 500 - Error response if post creation fails
* @example
* // Request body:
* {
* "title": "My First Post",
* "content": "This is the content of my post",
* "author": "John Doe"
* }
*/
app.post('/add-post', async (req, res) => {
try {
const postData = req.body;
const result = await insertPost(postData);
res.status(200).json({ success: true, result });
} catch (err) {
console.error('Error adding post:', err);
res.status(500).json({ success: false, error: err.toString() });
}
});
/**
* GET /get-posts - Retrieve all posts
* @name GetPosts
* @route {GET} /get-posts
* @description Retrieves all posts from the database
* @returns {Object} 200 - Success response with array of posts
* @returns {Object} 500 - Error response if retrieval fails
* @example
* // Success response:
* {
* "success": true,
* "result": [
* {
* "_id": "...",
* "title": "Post Title",
* "content": "Post content",
* "author": "Author Name"
* }
* ]
* }
*/
app.get('/get-posts', async (req, res) => {
try {
const result = await getAllPosts();
res.status(200).json({ success: true, result });
} catch (err) {
console.error('Error getting posts:', err);
res.status(500).json({ success: false, error: err.toString() });
}
});
/**
* POST /register - User registration endpoint
* @name RegisterUser
* @route {POST} /register
* @description Registers a new user with username, email, and password
* @param {Object} req.body - User registration data
* @param {string} req.body.username - User's chosen username
* @param {string} req.body.email - User's email address
* @param {string} req.body.password - User's password (will be hashed)
* @returns {Object} 201 - Success response with user data
* @returns {Object} 400 - Error response for validation failures or existing user
* @example
* // Request body:
* {
* "username": "johndoe",
* "email": "john@example.com",
* "password": "SecurePassword123"
* }
* // Success response:
* {
* "success": true,
* "message": "User registered successfully",
* "user": {
* "id": "...",
* "username": "johndoe",
* "email": "john@example.com"
* }
* }
*/
app.post('/register', async (req, res) => {
try {
const { username, email, password } = req.body;
if (!username || !email || !password) {
return res.status(400).json({
success: false,
error: 'Please provide username, email, and password'
});
}
const result = await registerUser(username, email, password);
res.status(201).json({
success: true,
message: 'User registered successfully',
user: {
id: result._id,
username: result.username,
email: result.email
}
});
} catch (err) {
console.error('Error registering user:', err);
res.status(400).json({
success: false,
error: err.message
});
}
});
/**
* POST /delete-user - Delete user account
* @name DeleteUser
* @route {POST} /delete-user
* @description Deletes a user account after verifying credentials
* @param {Object} req.body - User credentials for deletion
* @param {string} req.body.email - User's email address
* @param {string} req.body.password - User's password for verification
* @returns {Object} 200 - Success response confirming deletion
* @returns {Object} 400 - Error response for missing credentials
* @returns {Object} 500 - Error response for deletion failures
* @example
* // Request body:
* {
* "email": "john@example.com",
* "password": "SecurePassword123"
* }
*/
app.post('/delete-user', async (req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({
success: false,
error: 'Please provide email and password'
});
}
const result = await deleteaUser(email, password);
res.status(200).json({
success: true,
message: 'User deleted successfully'
});
} catch (err) {
console.error('Error deleting user:', err);
res.status(500).json({
success: false,
error: err.message
});
}
});
/**
* POST /login - User authentication endpoint
* @name LoginUser
* @route {POST} /login
* @description Authenticates a user with email and password
* @param {Object} req.body - User login credentials
* @param {string} req.body.email - User's email address
* @param {string} req.body.password - User's password
* @returns {Object} 200 - Success response with user data and JWT token
* @returns {Object} 400 - Error response for missing credentials
* @returns {Object} 401 - Error response for invalid credentials
* @example
* // Request body:
* {
* "email": "john@example.com",
* "password": "SecurePassword123"
* }
* // Success response:
* {
* "success": true,
* "message": "Login successful",
* "user": {
* "username": "johndoe",
* "email": "john@example.com",
* "token": "jwt_token_here"
* }
* }
*/
app.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({
success: false,
error: 'Please provide email and password'
});
}
const user = await LoginUser(email, password);
res.status(200).json({
success: true,
message: 'Login successful',
user: user
});
} catch (err) {
console.error('Error logging in user:', err);
res.status(401).json({
success: false,
error: err.message
});
}
});
// Start server only after MongoDB connection is established
app.listen(PORT, () => {
console.log(`Server listening on http://localhost:${PORT}`);
});
} catch (error) {
console.error('Failed to connect to MongoDB:', error);
console.error('Server will not start until MongoDB connection is established');
process.exit(1);
}
};
// Start the server only if this file is run directly (not imported for testing)
if (require.main === module) {
startServer();
}
// Export the app for testing
module.exports = app;