Overview
The Church Management System API uses JSON Web Tokens (JWT) for secure authentication. After logging in, you’ll receive a token that must be included in the Authorization header for all protected endpoints.
Authentication Flow
Register a new account
Create a user account with an email, password, and role.
Login with credentials
Receive a JWT token valid for 1 hour.
Include token in requests
Add the token to the Authorization header as Bearer <token>.
Token verification
The API verifies your token and extracts user ID and role.
Registration
Create a new user account by sending a POST request to /api/auth/register.
Endpoint
Request Body
{
"email" : "[email protected] " ,
"password" : "yourPassword123" ,
"role" : "member" ,
"invitedBy" : "admin"
}
Parameters
Field Type Required Description emailstring Yes User’s email address (must be unique) passwordstring Yes Password (minimum 6 characters) rolestring Yes User role: pastor or member (case-insensitive) invitedBystring No Who invited this user
Example Request
cURL
JavaScript (Fetch)
Python (Requests)
curl -X POST http://localhost:3001/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "securePass456",
"role": "member",
"invitedBy": "[email protected] "
}'
Response
201 Created
400 Bad Request
409 Conflict
{
"success" : true ,
"message" : "Registeration Successful" ,
"data" : "A verification link has been sent to you. Kindly verify your email address"
}
Passwords are hashed using bcrypt with 10 salt rounds before storage. Plain text passwords are never stored.
Login
Authenticate with your credentials to receive a JWT token.
Endpoint
Request Body
Example Request
cURL
JavaScript (Fetch)
Python (Requests)
curl -X POST http://localhost:3001/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "securePassword123"
}'
Response
200 OK
400 Bad Request
404 Not Found
{
"success" : true ,
"message" : "Login Successful" ,
"data" : {
"User" : {
"email" : "[email protected] " ,
"role" : "pastor" ,
"profile" : {},
"invitedBy" : "admin" ,
"isProfileComplete" : false ,
"createdAt" : "2026-03-07T10:30:00.000Z"
},
"token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY1YTFjMmQ0ZTVmNmE3YjhkOWMxMjM0NSIsInJvbGUiOiJwYXN0b3IiLCJpYXQiOjE3MDk4MTQ2MDAsImV4cCI6MTcwOTgxODIwMH0.xYz123..."
}
}
JWT Token Structure
The JWT token contains the following payload:
{
"id" : "65a1c2d4e5f6a7b8d9c12345" ,
"role" : "pastor" ,
"iat" : 1709814600 ,
"exp" : 1709818200
}
Field Description idUser’s MongoDB ObjectId roleUser’s role (pastor or member) iatIssued at timestamp expExpiration timestamp (1 hour from issue)
Tokens expire after 1 hour . You’ll need to login again to get a new token when it expires.
Using the Token
Include the JWT token in the Authorization header of all authenticated requests.
Authorization: Bearer <your-token-here>
Example Authenticated Request
cURL
JavaScript (Fetch)
Python (Requests)
curl -X GET http://localhost:3001/api/users/profile \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Token Verification Process
The API’s verifyToken middleware performs the following checks:
Looks for Authorization header (case-insensitive)
Verifies the header starts with “Bearer”
Extracts the token from Bearer <token>
Verifies the token signature using JWT_SECRET
Decodes and attaches user data to req.theUser
Implementation (src/middleware/authmiddleware.js:3-39):
const verifyToken = ( req , res , next ) => {
let authHeader = req . headers . authorization || req . headers . Authorization ;
if ( authHeader && authHeader . startsWith ( "Bearer" )) {
const theToken = authHeader . split ( " " )[ 1 ];
if ( ! theToken ) {
return res . status ( 400 ). send ({
success: false ,
message: "Access Denied" ,
data: "Access Token not Found"
});
} else {
try {
const decode = jwt . verify ( theToken , process . env . JWT_SECRET );
req . theUser = decode ; // Contains { id, role }
next ();
} catch ( err ) {
res . status ( 500 ). send ({
success: false ,
message: "Access Denied" ,
data: err . message
});
}
}
} else {
return res . status ( 400 ). send ({
success: false ,
message: "Access Denied" ,
data: "Authorization missing"
});
}
};
Role-Based Access Control
The API implements role-based authorization to restrict access to certain endpoints.
Available Roles
Role Description Access Level pastorChurch pastor/leader Full access to church management features memberRegular church member Limited access to member features
How Authorization Works
Protected routes use the authorizeRoles middleware to check user roles:
Implementation (src/middleware/rolemidddleware.js:1-14):
const authorizeRoles = ( theTokenRole ) => {
return ( req , res , next ) => {
if ( theTokenRole == req . theUser . role ) {
next ();
} else {
res . status ( 403 ). send ({
success: false ,
message: "Access Denied" ,
data: `The role ' ${ req . theUser . role } ' is not allowed for this route`
});
}
}
}
Example: Role-Protected Endpoint
const verifyToken = require ( './middleware/authmiddleware' );
const authorizeRoles = require ( './middleware/rolemidddleware' );
// Only pastors can access this route
router . post ( '/church/create' ,
verifyToken ,
authorizeRoles ( 'pastor' ),
createChurch
);
// Both pastors and members can access this route
router . get ( '/users/profile' ,
verifyToken ,
getProfile
);
Authorization Error Response
If a user tries to access a route they don’t have permission for:
{
"success" : false ,
"message" : "Access Denied" ,
"data" : "The role 'member' is not allowed for this route"
}
Common Authentication Errors
{
"success" : false ,
"message" : "Access Denied" ,
"data" : "Authorization missing"
}
Solution : Include the Authorization: Bearer <token> header in your request.
Invalid or Expired Token
500 Internal Server Error
{
"success" : false ,
"message" : "Access Denied" ,
"data" : "jwt expired"
}
Solution : Login again to get a new token.
{
"success" : false ,
"message" : "Access Denied" ,
"data" : "Access Token not Found"
}
Solution : Ensure your header is formatted as Bearer <token> with a space between “Bearer” and the token.
Security Best Practices
Environment Variables : Store your JWT_SECRET in the .env file and use a strong, random string (at least 32 characters).
Token Storage :
Frontend : Store tokens in memory or httpOnly cookies, not localStorage (XSS risk)
Mobile : Use secure storage like Keychain (iOS) or Keystore (Android)
Never expose tokens in URLs or logs
Password Security :
Passwords are hashed with bcrypt (10 salt rounds)
Minimum 6 characters enforced
Plain text passwords are never stored
Next Steps
API Reference Explore all available endpoints and their authentication requirements
User Management Learn how to manage user profiles and permissions