Skip to content

Commit f2477b3

Browse files
authored
Merge pull request #43 from saumya1317/docs/swagger-integration
docs: integrate Swagger for automated API documentation
2 parents 152c4a5 + 38aaaf8 commit f2477b3

File tree

11 files changed

+1430
-112
lines changed

11 files changed

+1430
-112
lines changed

package-lock.json

Lines changed: 329 additions & 98 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@
2323
"cors": "^2.8.5",
2424
"dotenv": "^17.2.3",
2525
"express": "^5.1.0",
26-
"helmet": "^8.1.0",
2726
"express-async-handler": "^1.2.0",
2827
"express-rate-limiter": "^1.3.1",
28+
"helmet": "^8.1.0",
2929
"joi": "^18.0.1",
3030
"jsonwebtoken": "^9.0.2",
3131
"mongoose": "^8.19.1",
3232
"morgan": "^1.10.1",
3333
"nodemon": "^3.1.10",
3434
"readdirp": "^4.1.2",
35-
"winston": "^3.18.3",
36-
"resend": "^6.1.3"
35+
"resend": "^6.1.3",
36+
"swagger-jsdoc": "^6.2.8",
37+
"swagger-ui-express": "^5.0.1",
38+
"winston": "^3.18.3"
3739
}
3840
}

src/app.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import cookieParser from "cookie-parser";
44
import helmet from "helmet";
55
import morgan from "morgan";
66
import dotenv from "dotenv";
7+
import swaggerUi from "swagger-ui-express";
78
import logger from "./config/logger.js";
9+
import swaggerSpec from "./config/swagger.js";
810
import authRoutes from "./routes/authRoutes.js";
911
import rbacRoutes from "./routes/rbacRoutes.js";
1012
import roleRoutes from "./routes/role.routes.js";
@@ -41,6 +43,17 @@ app.use(
4143
})
4244
);
4345

46+
// Swagger API Documentation
47+
app.use(
48+
"/api-docs",
49+
swaggerUi.serve,
50+
swaggerUi.setup(swaggerSpec, {
51+
explorer: true,
52+
customCss: '.swagger-ui .topbar { display: none }',
53+
customSiteTitle: 'RBAC API Docs',
54+
})
55+
);
56+
4457
// Routes
4558
app.use("/api/auth", authRoutes);
4659
app.use(rateLimiter);

src/config/dbconnection.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ const connectDB=async ()=>{
44
try {
55

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

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

1515
} catch (error) {
1616

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

2019
}
2120
}

src/config/swagger.js

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import swaggerJsDoc from 'swagger-jsdoc';
2+
3+
const swaggerOptions = {
4+
definition: {
5+
openapi: '3.0.0',
6+
info: {
7+
title: 'RBAC API Documentation',
8+
version: '1.0.0',
9+
description:
10+
'Role-Based Access Control (RBAC) API with JWT authentication. This API provides endpoints for user authentication, role management, permission management, and access control.',
11+
contact: {
12+
name: 'API Support',
13+
},
14+
license: {
15+
name: 'MIT',
16+
},
17+
},
18+
servers: [
19+
{
20+
url: 'http://localhost:5000',
21+
description: 'Development server',
22+
},
23+
],
24+
components: {
25+
securitySchemes: {
26+
bearerAuth: {
27+
type: 'http',
28+
scheme: 'bearer',
29+
bearerFormat: 'JWT',
30+
description: 'Enter your JWT token',
31+
},
32+
cookieAuth: {
33+
type: 'apiKey',
34+
in: 'cookie',
35+
name: 'refreshToken',
36+
description: 'Refresh token stored in HTTP-only cookie',
37+
},
38+
},
39+
schemas: {
40+
User: {
41+
type: 'object',
42+
required: ['username', 'email', 'password'],
43+
properties: {
44+
_id: {
45+
type: 'string',
46+
description: 'Auto-generated MongoDB ID',
47+
},
48+
username: {
49+
type: 'string',
50+
description: 'Unique username',
51+
minLength: 3,
52+
maxLength: 30,
53+
},
54+
email: {
55+
type: 'string',
56+
format: 'email',
57+
description: 'Unique email address',
58+
},
59+
password: {
60+
type: 'string',
61+
description: 'Hashed password',
62+
minLength: 6,
63+
},
64+
role: {
65+
type: 'string',
66+
description: 'Reference to Role model',
67+
},
68+
refreshToken: {
69+
type: 'string',
70+
description: 'JWT refresh token',
71+
},
72+
createdAt: {
73+
type: 'string',
74+
format: 'date-time',
75+
},
76+
updatedAt: {
77+
type: 'string',
78+
format: 'date-time',
79+
},
80+
},
81+
},
82+
Role: {
83+
type: 'object',
84+
required: ['name'],
85+
properties: {
86+
_id: {
87+
type: 'string',
88+
description: 'Auto-generated MongoDB ID',
89+
},
90+
name: {
91+
type: 'string',
92+
description: 'Unique role name',
93+
enum: ['Admin', 'User', 'Moderator'],
94+
},
95+
description: {
96+
type: 'string',
97+
description: 'Role description',
98+
},
99+
permissions: {
100+
type: 'array',
101+
items: {
102+
type: 'string',
103+
},
104+
description: 'Array of permission IDs associated with this role',
105+
},
106+
createdAt: {
107+
type: 'string',
108+
format: 'date-time',
109+
},
110+
updatedAt: {
111+
type: 'string',
112+
format: 'date-time',
113+
},
114+
},
115+
},
116+
Permission: {
117+
type: 'object',
118+
required: ['name', 'resource', 'action'],
119+
properties: {
120+
_id: {
121+
type: 'string',
122+
description: 'Auto-generated MongoDB ID',
123+
},
124+
name: {
125+
type: 'string',
126+
description: 'Unique permission name',
127+
},
128+
resource: {
129+
type: 'string',
130+
description: 'Resource this permission applies to',
131+
},
132+
action: {
133+
type: 'string',
134+
description: 'Action allowed on the resource',
135+
},
136+
description: {
137+
type: 'string',
138+
description: 'Permission description',
139+
},
140+
createdAt: {
141+
type: 'string',
142+
format: 'date-time',
143+
},
144+
updatedAt: {
145+
type: 'string',
146+
format: 'date-time',
147+
},
148+
},
149+
},
150+
Error: {
151+
type: 'object',
152+
properties: {
153+
success: {
154+
type: 'boolean',
155+
example: false,
156+
},
157+
message: {
158+
type: 'string',
159+
description: 'Error message',
160+
},
161+
statusCode: {
162+
type: 'integer',
163+
description: 'HTTP status code',
164+
},
165+
},
166+
},
167+
Success: {
168+
type: 'object',
169+
properties: {
170+
success: {
171+
type: 'boolean',
172+
example: true,
173+
},
174+
message: {
175+
type: 'string',
176+
description: 'Success message',
177+
},
178+
data: {
179+
type: 'object',
180+
description: 'Response data',
181+
},
182+
},
183+
},
184+
},
185+
},
186+
tags: [
187+
{
188+
name: 'Authentication',
189+
description: 'User authentication and authorization endpoints',
190+
},
191+
{
192+
name: 'Roles',
193+
description: 'Role management endpoints',
194+
},
195+
{
196+
name: 'Permissions',
197+
description: 'Permission management endpoints',
198+
},
199+
{
200+
name: 'RBAC Tests',
201+
description: 'Protected endpoints to test role-based access control',
202+
},
203+
],
204+
},
205+
apis: [
206+
'./src/routes/*.js',
207+
'./src/controllers/*.js',
208+
'./src/models/*.js',
209+
],
210+
};
211+
212+
const swaggerSpec = swaggerJsDoc(swaggerOptions);
213+
214+
export default swaggerSpec;

0 commit comments

Comments
 (0)