A content management backend for nonprofit organizations built with Node.js, Express, MongoDB, and JWT authentication.
| Layer | Technologies |
|---|---|
| Backend | Node.js + Express |
| Database | MongoDB (via Mongoose) |
| Auth | JWT + bcrypt |
| Tools | Postman, MongoDB Compass |
-
JWT Authentication using
protectmiddleware -
Role-Based Access Control (RBAC) via
authorizeRoles('admin', 'editor') -
User Profile Routes:
GET /api/users/me– Get authenticated user profilePUT /api/users/me– Update user’s name or email
-
Input Validation via
express-validatorfor input safety and structure
| Role | Permissions |
|---|---|
admin |
Full access to all resources |
editor |
Create and manage content |
viewer |
Read-only access to dashboard/data |
Using express-validator for all routes to ensure valid input data.
| Feature | Method | Endpoint | Required Fields |
|---|---|---|---|
| Team Members | POST | /api/team/ |
name, title, bio |
| PUT | /api/team/:id |
Optional: name, title, bio |
|
| Pages | POST | /api/pages/ |
title, slug, content |
| PUT | /api/pages/:id |
Optional: title, slug, content |
|
| Blog Posts | POST | /api/blog/ |
title, slug, content |
| PUT | /api/blog/:id |
Optional: title, slug, content |
|
| Events | POST | /api/events/ |
name, date, location, desc |
| PUT | /api/events/:id |
Optional: all fields above | |
| User Profile | PUT | /api/users/me |
Optional: name, email |
{
"errors": [
{
"msg": "Field is required",
"param": "fieldName",
"location": "body"
}
]
}| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/projects |
Retrieve all projects | ❌ No |
| POST | /api/projects |
Create new project | ✅ Yes |
| GET | /api/blogs |
Get list of blog posts | ❌ No |
| POST | /api/blogs |
Create new blog post | ✅ Yes |
| GET | /api/events |
Get upcoming events | ❌ No |
| POST | /api/events |
Add new event | ✅ Yes |
| GET | /api/pages/:slug |
Get dynamic page content | ❌ No |
Create a .env file in the root of the project:
PORT=5000
NODE_ENV=development
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRE=30d
MONGO_URI: Your MongoDB connection string (e.g. from Atlas or local instance)JWT_SECRET: A secret string used for signing JWTsJWT_EXPIRE: Token expiration (e.g.30dfor 30 days)
If you're using Docker:
docker build -t npo-cms-backend .
docker run -p 5000:5000 --env-file .env npo-cms-backendFor frontend deployments (React), connect your repo to Vercel or Netlify, and ensure that it points to the correct backend API URLs.
- Push your project to GitHub
- Link to a platform like Render, Railway, or Heroku (We have more options at the bottom of this read me)
- Set the same environment variables in their dashboard
- Make sure your frontend references the deployed backend URL
| Command | Description |
|---|---|
npm install |
Install dependencies |
npm run dev |
Start server in dev mode |
npm start |
Start server in production |
GitHub for Good – Free GitHub Team/Pro
Google for Nonprofits – Workspace, YouTube credits
Microsoft for Nonprofits – Azure credits
AWS Activate for Nonprofits – AWS credits for infra
| Backend Platform | Frontend Platform | DB Host | Notes |
|---|---|---|---|
| Railway (Free) | Vercel (Free) | MongoDB Atlas | Easiest setup, mostly free |
| Render (Free) | Netlify (Free) | MongoDB Atlas | Stable, nonprofit-friendly |
| Fly.io (Free) | Vercel | MongoDB Atlas | Powerful, but more technical setup |