jwt-middleware-auth 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +149 -0
- package/index.js +301 -44
- package/package.json +6 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Changelog - JWT Middleware Authentication
|
|
2
|
+
|
|
3
|
+
## 2025-12-08
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
#### User & Admin Access Control
|
|
8
|
+
- **`verifyUserOwnershipOrAdmin`** - Middleware for user-specific resource access control
|
|
9
|
+
- Validates that authenticated user can only access/modify their own data
|
|
10
|
+
- Grants automatic access to admin and SuperManager roles
|
|
11
|
+
- Extracts user ID from route params (`:id` or `:userId`)
|
|
12
|
+
- Returns 401 if user not authenticated
|
|
13
|
+
- Returns 403 if user attempts to access another user's data
|
|
14
|
+
- Example: `router.put('/user/:id', verifyToken(secret), verifyUserOwnershipOrAdmin, controller)`
|
|
15
|
+
- Use cases: User profile updates, user data retrieval, user deletion
|
|
16
|
+
|
|
17
|
+
- **`verifyAdminOrSuperManager`** - Middleware for admin-only operations
|
|
18
|
+
- Restricts access to users with admin or SuperManager roles
|
|
19
|
+
- Returns 401 if user not authenticated
|
|
20
|
+
- Returns 403 if user lacks admin privileges
|
|
21
|
+
- Example: `router.get('/users', verifyToken(secret), verifyAdminOrSuperManager, controller)`
|
|
22
|
+
- Use cases: Admin dashboards, user management, sensitive data endpoints
|
|
23
|
+
|
|
24
|
+
#### Seller & Multi-Role Verification
|
|
25
|
+
- **`verifySellerOrAdmin(secret)`** - Middleware for seller/manager/admin/SuperManager role verification
|
|
26
|
+
- Validates that user has one of the elevated privilege roles
|
|
27
|
+
- Supports: admin, seller, manager, SuperManager
|
|
28
|
+
- Returns 403 if user lacks required privileges
|
|
29
|
+
- Example: `router.get('/store/:id/orders', verifySellerOrAdmin(secret), controller)`
|
|
30
|
+
|
|
31
|
+
- **`verifySellerRole(secret)`** - Middleware for strict seller role verification
|
|
32
|
+
- Validates that the authenticated user has seller or paymentManager role
|
|
33
|
+
- Focused on role validation for creating resources (more specific than verifySeller)
|
|
34
|
+
- Returns 403 if user does not have required role
|
|
35
|
+
- Example: `router.post('/offers', verifySellerRole(secret), controller)`
|
|
36
|
+
|
|
37
|
+
#### Advanced Ownership Verification
|
|
38
|
+
- **`verifyTokenAndOwnership(secret, getResourceOwnerId)`** - Higher-order middleware factory for resource ownership verification
|
|
39
|
+
- Verifies JWT token AND checks that the authenticated user owns the resource
|
|
40
|
+
- Accepts async function to retrieve resource owner ID
|
|
41
|
+
- Handles resource not found errors with 404 status
|
|
42
|
+
- Compares owner ID with authenticated user ID (handles both ObjectId and string types)
|
|
43
|
+
- Returns 403 if user is not the resource owner
|
|
44
|
+
- Returns 404 if resource not found
|
|
45
|
+
- Returns 500 for ownership verification errors
|
|
46
|
+
- Example usage:
|
|
47
|
+
```javascript
|
|
48
|
+
const checkOfferOwnership = async (req) => {
|
|
49
|
+
const offer = await Offer.findById(req.params.id);
|
|
50
|
+
if (!offer) throw new Error('Offer not found');
|
|
51
|
+
return offer.sellerId;
|
|
52
|
+
};
|
|
53
|
+
router.put('/offer/:id', verifyTokenAndOwnership(secret, checkOfferOwnership), controller)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- **`verifyTokenAndMultiOwnership(secret, getResourceOwnerIds)`** - Advanced multi-ownership verification
|
|
57
|
+
- Higher-order middleware factory for resources with multiple potential owners
|
|
58
|
+
- Automatically grants access to admin and SuperManager roles
|
|
59
|
+
- Accepts async function that returns array of owner IDs
|
|
60
|
+
- Checks if authenticated user matches any owner ID
|
|
61
|
+
- Useful for complex resources like orders (client OR seller can access)
|
|
62
|
+
- Returns 403 if user is not an owner or admin
|
|
63
|
+
- Returns 404 if resource not found
|
|
64
|
+
- Example usage:
|
|
65
|
+
```javascript
|
|
66
|
+
const checkOrderOwnership = async (req) => {
|
|
67
|
+
const order = await Order.findById(req.params.id);
|
|
68
|
+
if (!order) throw new Error('Order not found');
|
|
69
|
+
const store = await Store.findById(order.storeId);
|
|
70
|
+
return [order.clientId, store.sellerId]; // Both can access
|
|
71
|
+
};
|
|
72
|
+
router.get('/order/:id', verifyTokenAndMultiOwnership(secret, checkOrderOwnership), controller)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Role-Based Access Control (RBAC)
|
|
76
|
+
- **`authorizeRoles(...allowedRoles)`** - Middleware function for role-based access control
|
|
77
|
+
- Verifies authenticated users have one of the allowed roles
|
|
78
|
+
- Must be used after `verifyToken` middleware
|
|
79
|
+
- Supports multiple roles with flexible authorization logic
|
|
80
|
+
- Returns 401 if user is not authenticated
|
|
81
|
+
- Returns 403 if user lacks required permissions
|
|
82
|
+
- Example: `authorizeRoles('admin', 'manager')`
|
|
83
|
+
|
|
84
|
+
#### Core Middleware (Previously Included)
|
|
85
|
+
- **`verifyToken(secret)`** - Middleware to verify JWT tokens from request headers
|
|
86
|
+
- Expects token in 'token' header as 'Bearer <token>'
|
|
87
|
+
- Populates `req.user` with decoded token payload
|
|
88
|
+
|
|
89
|
+
- **`verifyTokenAndAuthorization(secret)`** - Middleware for user self-update authorization
|
|
90
|
+
- Allows access if user is updating their own account OR is an admin
|
|
91
|
+
|
|
92
|
+
- **`verifyAdmin(secret)`** - Middleware to verify admin privileges
|
|
93
|
+
- Checks `req.user.isAdmin` property
|
|
94
|
+
|
|
95
|
+
- **`verifyManager(secret)`** - Middleware to verify manager role or self-access
|
|
96
|
+
- Allows access if user is a manager OR accessing their own resource
|
|
97
|
+
|
|
98
|
+
- **`verifySeller(secret)`** - Middleware to verify seller/payment manager role
|
|
99
|
+
- Allows access if user is a seller, payment manager, OR accessing their own resource
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
- Updated package description to reflect role-based authorization capabilities
|
|
103
|
+
- Enhanced JSDoc documentation for all middleware functions with detailed examples
|
|
104
|
+
- Added comprehensive inline comments explaining middleware behavior
|
|
105
|
+
- Exported all new middleware functions in module exports
|
|
106
|
+
- Package keywords updated to include: "authorization", "roles", "rbac"
|
|
107
|
+
|
|
108
|
+
### Improved
|
|
109
|
+
- Enhanced user data protection with ownership verification
|
|
110
|
+
- Centralized admin role verification for consistent access control
|
|
111
|
+
- Better separation of concerns between user-level and admin-level operations
|
|
112
|
+
- Enhanced support for multi-tenant authorization patterns
|
|
113
|
+
- Better handling of resources with multiple owners or access levels
|
|
114
|
+
- Consistent admin/SuperManager privilege handling across all ownership middlewares
|
|
115
|
+
- Enhanced flexibility for seller-related authorization with separate role-checking middleware
|
|
116
|
+
- Better separation of concerns between role verification and ownership verification
|
|
117
|
+
- Comprehensive error handling for resource ownership validation
|
|
118
|
+
- Better error handling in `authorizeRoles` middleware
|
|
119
|
+
- More descriptive error messages for authentication and authorization failures
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Summary
|
|
124
|
+
|
|
125
|
+
**Total Middleware Functions:** 13
|
|
126
|
+
|
|
127
|
+
**Categories:**
|
|
128
|
+
- Core Authentication: 1 (verifyToken)
|
|
129
|
+
- Admin & Role Verification: 4 (verifyAdmin, verifyAdminOrSuperManager, authorizeRoles, verifyManager)
|
|
130
|
+
- Seller Verification: 3 (verifySeller, verifySellerRole, verifySellerOrAdmin)
|
|
131
|
+
- Ownership & Authorization: 3 (verifyTokenAndAuthorization, verifyTokenAndOwnership, verifyTokenAndMultiOwnership)
|
|
132
|
+
- User Access Control: 1 (verifyUserOwnershipOrAdmin)
|
|
133
|
+
|
|
134
|
+
**Key Features:**
|
|
135
|
+
- ✅ Complete JWT token verification
|
|
136
|
+
- ✅ Flexible role-based access control (RBAC)
|
|
137
|
+
- ✅ Resource ownership verification (single & multi-owner)
|
|
138
|
+
- ✅ User self-access & admin privilege management
|
|
139
|
+
- ✅ Seller/Manager role validation
|
|
140
|
+
- ✅ Comprehensive error handling
|
|
141
|
+
- ✅ TypeScript-ready with JSDoc documentation
|
|
142
|
+
|
|
143
|
+
**Dependencies:**
|
|
144
|
+
- jsonwebtoken: ^9.0.3
|
|
145
|
+
|
|
146
|
+
**Migration Notes:**
|
|
147
|
+
- All changes are additive - existing code continues to work
|
|
148
|
+
- Custom authorization middleware can be replaced with centralized package functions
|
|
149
|
+
- Simply import new middleware functions alongside existing ones for enhanced capabilities
|
package/index.js
CHANGED
|
@@ -1,24 +1,66 @@
|
|
|
1
1
|
const jwt = require('jsonwebtoken');
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Middleware to verify JWT token from request headers
|
|
5
|
+
* Expects token in 'token' header as 'Bearer <token>'
|
|
6
|
+
* Populates req.user with decoded token payload
|
|
7
|
+
* @param {string} secret - JWT secret for token verification
|
|
8
|
+
* @returns {Function} Express middleware function
|
|
9
|
+
*/
|
|
3
10
|
const verifyToken = (secret) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
return (req, res, next) => {
|
|
12
|
+
const authHeader = req.headers.token;
|
|
13
|
+
|
|
14
|
+
if (authHeader) {
|
|
15
|
+
const token = authHeader.split(' ')[1];
|
|
16
|
+
jwt.verify(token, secret, (err, user) => {
|
|
17
|
+
if (err) {
|
|
18
|
+
return res.status(401).json({ message: 'Invalid Token' });
|
|
19
|
+
}
|
|
20
|
+
req.user = user;
|
|
21
|
+
next();
|
|
22
|
+
});
|
|
23
|
+
} else {
|
|
24
|
+
return res.status(401).json({ message: 'Token is not provided' });
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Middleware to check if the authenticated user has one of the allowed roles
|
|
31
|
+
* Must be used after verifyToken middleware as it expects req.user to be populated
|
|
32
|
+
* @param {...string} allowedRoles - Roles that are allowed to access the route
|
|
33
|
+
* @returns {Function} Express middleware function
|
|
34
|
+
* @example
|
|
35
|
+
* router.get('/admin-only', verifyToken(secret), authorizeRoles('admin'), controller)
|
|
36
|
+
* router.get('/multi-role', verifyToken(secret), authorizeRoles('admin', 'manager'), controller)
|
|
37
|
+
*/
|
|
38
|
+
const authorizeRoles = (...allowedRoles) => {
|
|
39
|
+
return (req, res, next) => {
|
|
40
|
+
try {
|
|
41
|
+
// Check if user is authenticated (should be set by verifyToken middleware)
|
|
42
|
+
if (!req.user) {
|
|
43
|
+
return res.status(401).json({ message: 'Authentication required' });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check if user has one of the allowed roles
|
|
47
|
+
if (!allowedRoles.includes(req.user.role)) {
|
|
48
|
+
return res.status(403).json({ message: 'Access denied. Insufficient permissions.' });
|
|
18
49
|
}
|
|
19
|
-
|
|
50
|
+
|
|
51
|
+
next();
|
|
52
|
+
} catch (err) {
|
|
53
|
+
next(err);
|
|
54
|
+
}
|
|
20
55
|
};
|
|
21
|
-
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Middleware for updating user information
|
|
60
|
+
* Allows access if user is updating their own account OR is an admin
|
|
61
|
+
* @param {string} secret - JWT secret for token verification
|
|
62
|
+
* @returns {Function} Express middleware function
|
|
63
|
+
*/
|
|
22
64
|
const verifyTokenAndAuthorization = (secret) => {
|
|
23
65
|
return (req, res, next) => {
|
|
24
66
|
verifyToken(secret)(req, res, () => {
|
|
@@ -30,39 +72,254 @@ const verifyTokenAndAuthorization = (secret) => {
|
|
|
30
72
|
};
|
|
31
73
|
};
|
|
32
74
|
|
|
33
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Middleware to verify if user is an admin
|
|
77
|
+
* @param {string} secret - JWT secret for token verification
|
|
78
|
+
* @returns {Function} Express middleware function
|
|
79
|
+
*/
|
|
34
80
|
const verifyAdmin = (secret) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
81
|
+
return (req, res, next) => {
|
|
82
|
+
verifyToken(secret)(req, res, () => {
|
|
83
|
+
if (req.user.isAdmin || req.user.isAdmin == true) {
|
|
84
|
+
return next();
|
|
85
|
+
}
|
|
86
|
+
return res.status(403).json({ message: 'You are not an admin' });
|
|
87
|
+
});
|
|
43
88
|
};
|
|
89
|
+
};
|
|
44
90
|
|
|
45
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Middleware to verify if user is a manager or accessing their own resource
|
|
93
|
+
* @param {string} secret - JWT secret for token verification
|
|
94
|
+
* @returns {Function} Express middleware function
|
|
95
|
+
*/
|
|
46
96
|
const verifyManager = (secret) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
};
|
|
97
|
+
return (req, res, next) => {
|
|
98
|
+
verifyToken(secret)(req, res, () => {
|
|
99
|
+
if (req.user.id == req.params.id || req.user.role == 'manager') {
|
|
100
|
+
return next();
|
|
101
|
+
}
|
|
102
|
+
return res.status(403).json({ message: 'You are not a manager' });
|
|
103
|
+
});
|
|
55
104
|
};
|
|
56
|
-
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Middleware to verify if user is a seller, payment manager, or accessing their own resource
|
|
109
|
+
* @param {string} secret - JWT secret for token verification
|
|
110
|
+
* @returns {Function} Express middleware function
|
|
111
|
+
*/
|
|
57
112
|
const verifySeller = (secret) => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
113
|
+
return (req, res, next) => {
|
|
114
|
+
verifyToken(secret)(req, res, () => {
|
|
115
|
+
if (req.user.id == req.params.id || req.user.role == 'seller' || req.user.role == 'paymentManager') {
|
|
116
|
+
return next();
|
|
117
|
+
}
|
|
118
|
+
return res.status(403).json({ message: 'You are not authorized' });
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Middleware to verify seller role and optionally check resource ownership
|
|
125
|
+
* More flexible than verifySeller - focuses on role validation for creating resources
|
|
126
|
+
* @param {string} secret - JWT secret for token verification
|
|
127
|
+
* @returns {Function} Express middleware function
|
|
128
|
+
* @example
|
|
129
|
+
* router.post('/offers', verifySellerRole(secret), controller)
|
|
130
|
+
*/
|
|
131
|
+
const verifySellerRole = (secret) => {
|
|
132
|
+
return (req, res, next) => {
|
|
133
|
+
verifyToken(secret)(req, res, () => {
|
|
134
|
+
if (req.user.role === 'seller' || req.user.role === 'paymentManager') {
|
|
135
|
+
return next();
|
|
136
|
+
}
|
|
137
|
+
return res.status(403).json({ message: 'Seller role required' });
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Higher-order middleware factory to verify token and check resource ownership
|
|
144
|
+
* Validates that the authenticated user owns the resource before allowing access
|
|
145
|
+
* @param {string} secret - JWT secret for token verification
|
|
146
|
+
* @param {Function} getResourceOwnerId - Async function that retrieves the owner ID of the resource
|
|
147
|
+
* Function receives (req) and should return the owner ID or throw error if resource not found
|
|
148
|
+
* @returns {Function} Express middleware function
|
|
149
|
+
* @example
|
|
150
|
+
* // For offer ownership check
|
|
151
|
+
* const checkOfferOwnership = async (req) => {
|
|
152
|
+
* const offer = await Offer.findById(req.params.id);
|
|
153
|
+
* if (!offer) throw new Error('Offer not found');
|
|
154
|
+
* return offer.sellerId;
|
|
155
|
+
* };
|
|
156
|
+
* router.put('/offer/:id', verifyTokenAndOwnership(secret, checkOfferOwnership), controller)
|
|
157
|
+
*/
|
|
158
|
+
const verifyTokenAndOwnership = (secret, getResourceOwnerId) => {
|
|
159
|
+
return (req, res, next) => {
|
|
160
|
+
verifyToken(secret)(req, res, async () => {
|
|
161
|
+
try {
|
|
162
|
+
const ownerId = await getResourceOwnerId(req);
|
|
163
|
+
|
|
164
|
+
// Convert both to strings for comparison to handle ObjectId and string types
|
|
165
|
+
if (ownerId.toString() === req.user.id.toString()) {
|
|
166
|
+
return next();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return res.status(403).json({ message: 'You are not authorized to access this resource' });
|
|
170
|
+
} catch (error) {
|
|
171
|
+
// If resource not found or other errors during ownership check
|
|
172
|
+
if (error.message.includes('not found')) {
|
|
173
|
+
return res.status(404).json({ message: error.message });
|
|
174
|
+
}
|
|
175
|
+
return res.status(500).json({ message: 'Error verifying resource ownership' });
|
|
176
|
+
}
|
|
177
|
+
});
|
|
66
178
|
};
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Middleware to verify seller, manager, admin, or SuperManager roles
|
|
183
|
+
* Used for operations that require elevated privileges
|
|
184
|
+
* @param {string} secret - JWT secret for token verification
|
|
185
|
+
* @returns {Function} Express middleware function
|
|
186
|
+
* @example
|
|
187
|
+
* router.get('/store/:id/orders', verifySellerOrAdmin(secret), controller)
|
|
188
|
+
*/
|
|
189
|
+
const verifySellerOrAdmin = (secret) => {
|
|
190
|
+
return (req, res, next) => {
|
|
191
|
+
verifyToken(secret)(req, res, () => {
|
|
192
|
+
const allowedRoles = ['admin', 'seller', 'manager', 'SuperManager'];
|
|
193
|
+
if (allowedRoles.includes(req.user.role)) {
|
|
194
|
+
return next();
|
|
195
|
+
}
|
|
196
|
+
return res.status(403).json({ message: 'Access denied. Seller or admin privileges required' });
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Higher-order middleware factory for complex ownership verification
|
|
203
|
+
* Allows access if user is admin/SuperManager OR matches one of the owner IDs
|
|
204
|
+
* Useful for resources that can have multiple owners (e.g., orders - client or seller)
|
|
205
|
+
* @param {string} secret - JWT secret for token verification
|
|
206
|
+
* @param {Function} getResourceOwnerIds - Async function that retrieves owner IDs
|
|
207
|
+
* Function receives (req) and should return an array of owner IDs or throw error
|
|
208
|
+
* @returns {Function} Express middleware function
|
|
209
|
+
* @example
|
|
210
|
+
* // For order ownership check (client or seller of the store)
|
|
211
|
+
* const checkOrderOwnership = async (req) => {
|
|
212
|
+
* const order = await Order.findById(req.params.id);
|
|
213
|
+
* if (!order) throw new Error('Order not found');
|
|
214
|
+
* const store = await Store.findById(order.storeId);
|
|
215
|
+
* return [order.clientId, store.sellerId]; // Both can access
|
|
216
|
+
* };
|
|
217
|
+
* router.get('/order/:id', verifyTokenAndMultiOwnership(secret, checkOrderOwnership), controller)
|
|
218
|
+
*/
|
|
219
|
+
const verifyTokenAndMultiOwnership = (secret, getResourceOwnerIds) => {
|
|
220
|
+
return (req, res, next) => {
|
|
221
|
+
verifyToken(secret)(req, res, async () => {
|
|
222
|
+
try {
|
|
223
|
+
// Admin and SuperManager can access all resources
|
|
224
|
+
if (req.user.role === 'admin' || req.user.role === 'SuperManager') {
|
|
225
|
+
return next();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const ownerIds = await getResourceOwnerIds(req);
|
|
229
|
+
const userId = req.user.id.toString();
|
|
230
|
+
|
|
231
|
+
// Check if user ID matches any of the owner IDs
|
|
232
|
+
const hasAccess = ownerIds.some(ownerId => ownerId.toString() === userId);
|
|
233
|
+
|
|
234
|
+
if (hasAccess) {
|
|
235
|
+
return next();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return res.status(403).json({ message: 'Access denied to this resource' });
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (error.message.includes('not found')) {
|
|
241
|
+
return res.status(404).json({ message: error.message });
|
|
242
|
+
}
|
|
243
|
+
return res.status(500).json({ message: 'Error verifying resource ownership' });
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Middleware to verify that the authenticated user can only access/modify their own data
|
|
251
|
+
* or is an admin who can access any data
|
|
252
|
+
* Designed for user-specific endpoints where ID is in route params
|
|
253
|
+
* @param {Object} req - Express request object
|
|
254
|
+
* @param {Object} res - Express response object
|
|
255
|
+
* @param {Function} next - Express next middleware function
|
|
256
|
+
* @returns {Function} Express middleware function
|
|
257
|
+
* @example
|
|
258
|
+
* router.put('/user/:id', verifyToken(secret), verifyUserOwnershipOrAdmin, controller)
|
|
259
|
+
* router.get('/user/find/:id', verifyToken(secret), verifyUserOwnershipOrAdmin, controller)
|
|
260
|
+
*/
|
|
261
|
+
const verifyUserOwnershipOrAdmin = (req, res, next) => {
|
|
262
|
+
try {
|
|
263
|
+
// req.user is set by verifyToken middleware
|
|
264
|
+
if (!req.user) {
|
|
265
|
+
return res.status(401).json({ message: 'Authentication required' });
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const authenticatedUserId = req.user.id;
|
|
269
|
+
const requestedUserId = req.params.id || req.params.userId;
|
|
270
|
+
const userRole = req.user.role;
|
|
271
|
+
|
|
272
|
+
// Allow if user is accessing their own data or is an admin
|
|
273
|
+
if (authenticatedUserId === requestedUserId || userRole === 'admin' || userRole === 'SuperManager') {
|
|
274
|
+
return next();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return res.status(403).json({ message: 'Access denied. You can only access your own data' });
|
|
278
|
+
} catch (err) {
|
|
279
|
+
next(err);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Middleware to verify admin or SuperManager role
|
|
285
|
+
* Restricts access to admin-only operations
|
|
286
|
+
* @param {Object} req - Express request object
|
|
287
|
+
* @param {Object} res - Express response object
|
|
288
|
+
* @param {Function} next - Express next middleware function
|
|
289
|
+
* @returns {Function} Express middleware function
|
|
290
|
+
* @example
|
|
291
|
+
* router.get('/users', verifyToken(secret), verifyAdminOrSuperManager, controller)
|
|
292
|
+
* router.get('/sellers', verifyToken(secret), verifyAdminOrSuperManager, controller)
|
|
293
|
+
*/
|
|
294
|
+
const verifyAdminOrSuperManager = (req, res, next) => {
|
|
295
|
+
try {
|
|
296
|
+
if (!req.user) {
|
|
297
|
+
return res.status(401).json({ message: 'Authentication required' });
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const userRole = req.user.role;
|
|
301
|
+
|
|
302
|
+
if (userRole === 'admin' || userRole === 'SuperManager') {
|
|
303
|
+
return next();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return res.status(403).json({ message: 'Access denied. Admin privileges required' });
|
|
307
|
+
} catch (err) {
|
|
308
|
+
next(err);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
67
311
|
|
|
68
|
-
module.exports = {
|
|
312
|
+
module.exports = {
|
|
313
|
+
verifyToken,
|
|
314
|
+
authorizeRoles,
|
|
315
|
+
verifySeller,
|
|
316
|
+
verifySellerRole,
|
|
317
|
+
verifyTokenAndOwnership,
|
|
318
|
+
verifySellerOrAdmin,
|
|
319
|
+
verifyTokenAndMultiOwnership,
|
|
320
|
+
verifyUserOwnershipOrAdmin,
|
|
321
|
+
verifyAdminOrSuperManager,
|
|
322
|
+
verifyAdmin,
|
|
323
|
+
verifyTokenAndAuthorization,
|
|
324
|
+
verifyManager
|
|
325
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jwt-middleware-auth",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "A comprehensive middleware library for JWT authentication and role-based authorization in Express.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
"jwt",
|
|
11
11
|
"express",
|
|
12
12
|
"middleware",
|
|
13
|
-
"auth"
|
|
13
|
+
"auth",
|
|
14
|
+
"authorization",
|
|
15
|
+
"roles",
|
|
16
|
+
"rbac"
|
|
14
17
|
],
|
|
15
18
|
"license": "MIT",
|
|
16
19
|
"dependencies": {
|