Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
427 changes: 329 additions & 98 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@
"cors": "^2.8.5",
"dotenv": "^17.2.3",
"express": "^5.1.0",
"helmet": "^8.1.0",
"express-async-handler": "^1.2.0",
"express-rate-limiter": "^1.3.1",
"helmet": "^8.1.0",
"joi": "^18.0.1",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.19.1",
"morgan": "^1.10.1",
"nodemon": "^3.1.10",
"readdirp": "^4.1.2",
"winston": "^3.18.3",
"resend": "^6.1.3"
"resend": "^6.1.3",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"winston": "^3.18.3"
}
}
13 changes: 13 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import cookieParser from "cookie-parser";
import helmet from "helmet";
import morgan from "morgan";
import dotenv from "dotenv";
import swaggerUi from "swagger-ui-express";
import logger from "./config/logger.js";
import swaggerSpec from "./config/swagger.js";
import authRoutes from "./routes/authRoutes.js";
import rbacRoutes from "./routes/rbacRoutes.js";
import roleRoutes from "./routes/role.routes.js";
Expand Down Expand Up @@ -41,6 +43,17 @@ app.use(
})
);

// Swagger API Documentation
app.use(
"/api-docs",
swaggerUi.serve,
swaggerUi.setup(swaggerSpec, {
explorer: true,
customCss: '.swagger-ui .topbar { display: none }',
customSiteTitle: 'RBAC API Docs',
})
);

// Routes
app.use("/api/auth", authRoutes);
app.use(rateLimiter);
Expand Down
7 changes: 3 additions & 4 deletions src/config/dbconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const connectDB=async ()=>{
try {

if(!process.env.MONGO_URI){
console.error('MONGO_URI not found in .env');
process.exit(1);
console.warn('MONGO_URI not found in .env - database features will be unavailable');
return;
}

await mongoose.connect(`${process.env.MONGO_URI}`)
Expand All @@ -14,8 +14,7 @@ const connectDB=async ()=>{

} catch (error) {

console.log("Mongodb connnection error : ",error);
process.exit(1)
console.warn("Mongodb connection error - database features will be unavailable:",error.message);

}
}
Expand Down
214 changes: 214 additions & 0 deletions src/config/swagger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import swaggerJsDoc from 'swagger-jsdoc';

const swaggerOptions = {
definition: {
openapi: '3.0.0',
info: {
title: 'RBAC API Documentation',
version: '1.0.0',
description:
'Role-Based Access Control (RBAC) API with JWT authentication. This API provides endpoints for user authentication, role management, permission management, and access control.',
contact: {
name: 'API Support',
},
license: {
name: 'MIT',
},
},
servers: [
{
url: 'http://localhost:5000',
description: 'Development server',
},
],
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description: 'Enter your JWT token',
},
cookieAuth: {
type: 'apiKey',
in: 'cookie',
name: 'refreshToken',
description: 'Refresh token stored in HTTP-only cookie',
},
},
schemas: {
User: {
type: 'object',
required: ['username', 'email', 'password'],
properties: {
_id: {
type: 'string',
description: 'Auto-generated MongoDB ID',
},
username: {
type: 'string',
description: 'Unique username',
minLength: 3,
maxLength: 30,
},
email: {
type: 'string',
format: 'email',
description: 'Unique email address',
},
password: {
type: 'string',
description: 'Hashed password',
minLength: 6,
},
role: {
type: 'string',
description: 'Reference to Role model',
},
refreshToken: {
type: 'string',
description: 'JWT refresh token',
},
createdAt: {
type: 'string',
format: 'date-time',
},
updatedAt: {
type: 'string',
format: 'date-time',
},
},
},
Role: {
type: 'object',
required: ['name'],
properties: {
_id: {
type: 'string',
description: 'Auto-generated MongoDB ID',
},
name: {
type: 'string',
description: 'Unique role name',
enum: ['Admin', 'User', 'Moderator'],
},
description: {
type: 'string',
description: 'Role description',
},
permissions: {
type: 'array',
items: {
type: 'string',
},
description: 'Array of permission IDs associated with this role',
},
createdAt: {
type: 'string',
format: 'date-time',
},
updatedAt: {
type: 'string',
format: 'date-time',
},
},
},
Permission: {
type: 'object',
required: ['name', 'resource', 'action'],
properties: {
_id: {
type: 'string',
description: 'Auto-generated MongoDB ID',
},
name: {
type: 'string',
description: 'Unique permission name',
},
resource: {
type: 'string',
description: 'Resource this permission applies to',
},
action: {
type: 'string',
description: 'Action allowed on the resource',
},
description: {
type: 'string',
description: 'Permission description',
},
createdAt: {
type: 'string',
format: 'date-time',
},
updatedAt: {
type: 'string',
format: 'date-time',
},
},
},
Error: {
type: 'object',
properties: {
success: {
type: 'boolean',
example: false,
},
message: {
type: 'string',
description: 'Error message',
},
statusCode: {
type: 'integer',
description: 'HTTP status code',
},
},
},
Success: {
type: 'object',
properties: {
success: {
type: 'boolean',
example: true,
},
message: {
type: 'string',
description: 'Success message',
},
data: {
type: 'object',
description: 'Response data',
},
},
},
},
},
tags: [
{
name: 'Authentication',
description: 'User authentication and authorization endpoints',
},
{
name: 'Roles',
description: 'Role management endpoints',
},
{
name: 'Permissions',
description: 'Permission management endpoints',
},
{
name: 'RBAC Tests',
description: 'Protected endpoints to test role-based access control',
},
],
},
apis: [
'./src/routes/*.js',
'./src/controllers/*.js',
'./src/models/*.js',
],
};

const swaggerSpec = swaggerJsDoc(swaggerOptions);

export default swaggerSpec;
Loading
Loading