mbkauthe 1.3.5 → 1.4.1
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/.github/PACKAGE.md +17 -0
- package/.github/workflows/publish.yml +14 -2
- package/README.md +249 -187
- package/docs/api.md +841 -0
- package/index.js +13 -2
- package/lib/main.js +104 -31
- package/lib/pool.js +8 -8
- package/lib/validateSessionAndRole.js +55 -29
- package/package.json +8 -5
- package/public/main.js +134 -0
- package/views/2fa.handlebars +35 -445
- package/views/Error/dError.handlebars +71 -551
- package/views/info.handlebars +180 -160
- package/views/loginmbkauthe.handlebars +37 -557
- package/views/sharedStyles.handlebars +498 -0
- package/views/showmessage.handlebars +97 -62
package/docs/api.md
ADDED
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
# MBKAuthe API Documentation
|
|
2
|
+
|
|
3
|
+
[← Back to README](../README.md)
|
|
4
|
+
|
|
5
|
+
This document provides comprehensive API documentation for MBKAuthe authentication system.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Authentication](#authentication)
|
|
12
|
+
- [Session Management](#session-management)
|
|
13
|
+
- [API Endpoints](#api-endpoints)
|
|
14
|
+
- [Middleware Reference](#middleware-reference)
|
|
15
|
+
- [Code Examples](#code-examples)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Authentication
|
|
20
|
+
|
|
21
|
+
MBKAuthe supports two authentication methods:
|
|
22
|
+
|
|
23
|
+
1. **Session-based Authentication** - Cookie-based sessions for web applications
|
|
24
|
+
2. **Token-based Authentication** - API key authentication for server-to-server communication
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Session Management
|
|
29
|
+
|
|
30
|
+
### Session Cookie
|
|
31
|
+
|
|
32
|
+
When a user logs in, MBKAuthe creates a session and sets the following cookies:
|
|
33
|
+
|
|
34
|
+
| Cookie Name | Description | HttpOnly | Secure | SameSite |
|
|
35
|
+
|------------|-------------|----------|--------|----------|
|
|
36
|
+
| `mbkauthe.sid` | Session identifier | ✓ | Auto* | lax |
|
|
37
|
+
| `sessionId` | User session ID | ✓ | Auto* | lax |
|
|
38
|
+
| `username` | Username | ✗ | Auto* | lax |
|
|
39
|
+
|
|
40
|
+
\* `secure` flag is automatically set to `true` in production when `IS_DEPLOYED=true`
|
|
41
|
+
|
|
42
|
+
### Session Lifetime
|
|
43
|
+
|
|
44
|
+
- Default: 2 days (configurable via `COOKIE_EXPIRE_TIME`)
|
|
45
|
+
- Sessions are stored in PostgreSQL
|
|
46
|
+
- Sessions persist across subdomains in production
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## API Endpoints
|
|
51
|
+
|
|
52
|
+
### Public Endpoints
|
|
53
|
+
|
|
54
|
+
#### `GET /mbkauthe/login`
|
|
55
|
+
|
|
56
|
+
Renders the login page.
|
|
57
|
+
|
|
58
|
+
**Query Parameters:**
|
|
59
|
+
- `redirect` (optional) - URL to redirect after successful login
|
|
60
|
+
|
|
61
|
+
**Response:** HTML page
|
|
62
|
+
|
|
63
|
+
**Example:**
|
|
64
|
+
```
|
|
65
|
+
GET /mbkauthe/login?redirect=/dashboard
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
#### `POST /mbkauthe/api/login`
|
|
71
|
+
|
|
72
|
+
Authenticates a user and creates a session.
|
|
73
|
+
|
|
74
|
+
**Rate Limit:** 8 requests per minute
|
|
75
|
+
|
|
76
|
+
**Request Body:**
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"username": "string (required, 1-255 chars)",
|
|
80
|
+
"password": "string (required, 8-255 chars)"
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Success Response (200 OK):**
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"success": true,
|
|
88
|
+
"message": "Login successful",
|
|
89
|
+
"sessionId": "64-character-hex-string"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Success Response with 2FA (200 OK):**
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"success": true,
|
|
97
|
+
"twoFactorRequired": true
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Error Responses:**
|
|
102
|
+
|
|
103
|
+
| Status Code | Message |
|
|
104
|
+
|------------|------------|---------|
|
|
105
|
+
| 400 | Username and password are required |
|
|
106
|
+
| 400 | Invalid username format |
|
|
107
|
+
| 400 | Password must be at least 8 characters long |
|
|
108
|
+
| 401 | Incorrect Username Or Password |
|
|
109
|
+
| 403 | Account is inactive |
|
|
110
|
+
| 403 | You Are Not Authorized To Use The Application |
|
|
111
|
+
| 404 | Incorrect Username Or Password |
|
|
112
|
+
| 429 | Too many attempts, please try again later |
|
|
113
|
+
| 500 | 605 | Internal Server Error |
|
|
114
|
+
|
|
115
|
+
**Example Request:**
|
|
116
|
+
```javascript
|
|
117
|
+
fetch('/mbkauthe/api/login', {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
headers: {
|
|
120
|
+
'Content-Type': 'application/json',
|
|
121
|
+
},
|
|
122
|
+
body: JSON.stringify({
|
|
123
|
+
username: 'john.doe',
|
|
124
|
+
password: 'securePassword123'
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
.then(response => response.json())
|
|
128
|
+
.then(data => {
|
|
129
|
+
if (data.success && data.twoFactorRequired) {
|
|
130
|
+
// Redirect to 2FA page
|
|
131
|
+
window.location.href = '/mbkauthe/2fa';
|
|
132
|
+
} else if (data.success) {
|
|
133
|
+
// Login successful
|
|
134
|
+
window.location.href = data.redirectUrl || '/dashboard';
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
#### `GET /mbkauthe/2fa`
|
|
142
|
+
|
|
143
|
+
Renders the Two-Factor Authentication verification page.
|
|
144
|
+
|
|
145
|
+
**Prerequisites:** User must have completed initial login with valid credentials
|
|
146
|
+
|
|
147
|
+
**Response:** HTML page
|
|
148
|
+
|
|
149
|
+
**Note:** Redirects to `/mbkauthe/login` if no pre-authentication session exists
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
#### `POST /mbkauthe/api/verify-2fa`
|
|
154
|
+
|
|
155
|
+
Verifies the 2FA token and completes the login process.
|
|
156
|
+
|
|
157
|
+
**Rate Limit:** 5 requests per minute
|
|
158
|
+
|
|
159
|
+
**CSRF Protection:** Required (token must be included)
|
|
160
|
+
|
|
161
|
+
**Request Body:**
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"token": "string (required, 6-digit numeric code)",
|
|
165
|
+
"_csrf": "string (required, CSRF token)"
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Success Response (200 OK):**
|
|
170
|
+
```json
|
|
171
|
+
{
|
|
172
|
+
"success": true,
|
|
173
|
+
"message": "Login successful",
|
|
174
|
+
"sessionId": "64-character-hex-string",
|
|
175
|
+
"redirectUrl": "/dashboard"
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Error Responses:**
|
|
180
|
+
|
|
181
|
+
| Status Code | Message |
|
|
182
|
+
|------------|---------|
|
|
183
|
+
| 400 | 2FA token is required |
|
|
184
|
+
| 400 | Invalid 2FA token format |
|
|
185
|
+
| 401 | Not authorized. Please login first. |
|
|
186
|
+
| 401 | Invalid 2FA code |
|
|
187
|
+
| 429 | Too many 2FA attempts, please try again later |
|
|
188
|
+
| 500 | 2FA is not configured correctly. |
|
|
189
|
+
| 500 | Internal Server Error |
|
|
190
|
+
|
|
191
|
+
**Example Request:**
|
|
192
|
+
```javascript
|
|
193
|
+
fetch('/mbkauthe/api/verify-2fa', {
|
|
194
|
+
method: 'POST',
|
|
195
|
+
headers: {
|
|
196
|
+
'Content-Type': 'application/json',
|
|
197
|
+
},
|
|
198
|
+
body: JSON.stringify({
|
|
199
|
+
token: '123456',
|
|
200
|
+
_csrf: csrfToken
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
.then(response => response.json())
|
|
204
|
+
.then(data => {
|
|
205
|
+
if (data.success) {
|
|
206
|
+
window.location.href = data.redirectUrl;
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### Protected Endpoints
|
|
214
|
+
|
|
215
|
+
#### `POST /mbkauthe/api/logout`
|
|
216
|
+
|
|
217
|
+
Logs out the current user and destroys the session.
|
|
218
|
+
|
|
219
|
+
**Rate Limit:** 10 requests per minute
|
|
220
|
+
|
|
221
|
+
**CSRF Protection:** Required
|
|
222
|
+
|
|
223
|
+
**Authentication:** Session required
|
|
224
|
+
|
|
225
|
+
**Request Body:**
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"_csrf": "string (required, CSRF token)"
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Success Response (200 OK):**
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"success": true,
|
|
236
|
+
"message": "Logout successful"
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Error Responses:**
|
|
241
|
+
|
|
242
|
+
| Status Code | Message |
|
|
243
|
+
|------------|---------|
|
|
244
|
+
| 400 | Not logged in |
|
|
245
|
+
| 429 | Too many logout attempts, please try again later |
|
|
246
|
+
| 500 | Logout failed |
|
|
247
|
+
| 500 | Internal Server Error |
|
|
248
|
+
|
|
249
|
+
**Example Request:**
|
|
250
|
+
```javascript
|
|
251
|
+
fetch('/mbkauthe/api/logout', {
|
|
252
|
+
method: 'POST',
|
|
253
|
+
headers: {
|
|
254
|
+
'Content-Type': 'application/json',
|
|
255
|
+
},
|
|
256
|
+
body: JSON.stringify({
|
|
257
|
+
_csrf: csrfToken
|
|
258
|
+
})
|
|
259
|
+
})
|
|
260
|
+
.then(response => response.json())
|
|
261
|
+
.then(data => {
|
|
262
|
+
if (data.success) {
|
|
263
|
+
window.location.href = '/mbkauthe/login';
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
#### `POST /mbkauthe/api/terminateAllSessions`
|
|
271
|
+
|
|
272
|
+
Terminates all active sessions across all users (admin only).
|
|
273
|
+
|
|
274
|
+
**Authentication:** API token required
|
|
275
|
+
|
|
276
|
+
**Headers:**
|
|
277
|
+
```
|
|
278
|
+
Authorization: your-api-token
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Success Response (200 OK):**
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"success": true,
|
|
285
|
+
"message": "All sessions terminated successfully"
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Error Responses:**
|
|
290
|
+
|
|
291
|
+
| Status Code | Message |
|
|
292
|
+
|------------|---------|
|
|
293
|
+
| 401 | Unauthorized |
|
|
294
|
+
| 500 | Failed to terminate sessions |
|
|
295
|
+
| 500 | Internal Server Error |
|
|
296
|
+
|
|
297
|
+
**Example Request:**
|
|
298
|
+
```javascript
|
|
299
|
+
fetch('/mbkauthe/api/terminateAllSessions', {
|
|
300
|
+
method: 'POST',
|
|
301
|
+
headers: {
|
|
302
|
+
'Authorization': 'your-secret-token',
|
|
303
|
+
}
|
|
304
|
+
})
|
|
305
|
+
.then(response => response.json())
|
|
306
|
+
.then(data => console.log(data));
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### Information Endpoints
|
|
312
|
+
|
|
313
|
+
#### `GET /mbkauthe/info`
|
|
314
|
+
|
|
315
|
+
Displays MBKAuthe version information and configuration.
|
|
316
|
+
|
|
317
|
+
**Aliases:** `/mbkauthe/i`
|
|
318
|
+
|
|
319
|
+
**Rate Limit:** 8 requests per minute
|
|
320
|
+
|
|
321
|
+
**Response:** HTML page showing:
|
|
322
|
+
- Current version
|
|
323
|
+
- Latest available version
|
|
324
|
+
- Configuration settings (sanitized)
|
|
325
|
+
- Update notification if newer version available
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
#### `GET /mbkauthe/main.js`
|
|
330
|
+
|
|
331
|
+
Serves the client-side JavaScript file.
|
|
332
|
+
|
|
333
|
+
**Response:** JavaScript file (Content-Type: application/javascript)
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Middleware Reference
|
|
338
|
+
|
|
339
|
+
### `validateSession`
|
|
340
|
+
|
|
341
|
+
Validates that the user has an active session.
|
|
342
|
+
|
|
343
|
+
**Usage:**
|
|
344
|
+
```javascript
|
|
345
|
+
import { validateSession } from 'mbkauthe';
|
|
346
|
+
|
|
347
|
+
app.get('/protected', validateSession, (req, res) => {
|
|
348
|
+
// User is authenticated
|
|
349
|
+
const user = req.session.user;
|
|
350
|
+
// user contains: { id, username, UserName, role, Role, sessionId, allowedApps }
|
|
351
|
+
res.send(`Welcome ${user.username}!`);
|
|
352
|
+
});
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Behavior:**
|
|
356
|
+
- Checks for active session in `req.session.user`
|
|
357
|
+
- Attempts to restore session from `sessionId` cookie if session not found
|
|
358
|
+
- Validates session against database
|
|
359
|
+
- Checks if user account is still active
|
|
360
|
+
- Verifies user is authorized for the current application
|
|
361
|
+
- Redirects to login page if validation fails
|
|
362
|
+
|
|
363
|
+
**Session Object:**
|
|
364
|
+
```javascript
|
|
365
|
+
req.session.user = {
|
|
366
|
+
id: 1, // User ID
|
|
367
|
+
username: "john.doe", // Username
|
|
368
|
+
UserName: "john.doe", // Username (alias)
|
|
369
|
+
role: "NormalUser", // User role
|
|
370
|
+
Role: "NormalUser", // User role (alias)
|
|
371
|
+
sessionId: "abc123...", // 64-char hex session ID
|
|
372
|
+
allowedApps: ["app1"] // Array of allowed applications
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
### `checkRolePermission(requiredRole, notAllowed)`
|
|
379
|
+
|
|
380
|
+
Checks if the authenticated user has the required role.
|
|
381
|
+
|
|
382
|
+
**Parameters:**
|
|
383
|
+
- `requiredRole` (string) - Required role: `"SuperAdmin"`, `"NormalUser"`, `"Guest"`, or `"Any"`/`"any"`
|
|
384
|
+
- `notAllowed` (string, optional) - Role that is explicitly not allowed
|
|
385
|
+
|
|
386
|
+
**Usage:**
|
|
387
|
+
```javascript
|
|
388
|
+
import { validateSession, checkRolePermission } from 'mbkauthe';
|
|
389
|
+
|
|
390
|
+
// Only SuperAdmin can access
|
|
391
|
+
app.get('/admin', validateSession, checkRolePermission('SuperAdmin'), (req, res) => {
|
|
392
|
+
res.send('Admin panel');
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
// Any authenticated user except Guest
|
|
396
|
+
app.get('/content', validateSession, checkRolePermission('Any', 'Guest'), (req, res) => {
|
|
397
|
+
res.send('Protected content');
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**Behavior:**
|
|
402
|
+
- Checks if user is authenticated first
|
|
403
|
+
- Fetches user role from database
|
|
404
|
+
- Returns 403 if user has `notAllowed` role
|
|
405
|
+
- Returns 403 if user doesn't have `requiredRole` (unless role is "Any")
|
|
406
|
+
- Calls `next()` if authorized
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
### `validateSessionAndRole(requiredRole, notAllowed)`
|
|
411
|
+
|
|
412
|
+
Combined middleware for session validation and role checking.
|
|
413
|
+
|
|
414
|
+
**Parameters:**
|
|
415
|
+
- `requiredRole` (string) - Required role
|
|
416
|
+
- `notAllowed` (string, optional) - Role that is explicitly not allowed
|
|
417
|
+
|
|
418
|
+
**Usage:**
|
|
419
|
+
```javascript
|
|
420
|
+
import { validateSessionAndRole } from 'mbkauthe';
|
|
421
|
+
|
|
422
|
+
// Validate session AND check role in one middleware
|
|
423
|
+
app.get('/moderator', validateSessionAndRole('SuperAdmin'), (req, res) => {
|
|
424
|
+
res.send('Moderator panel');
|
|
425
|
+
});
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Equivalent to:**
|
|
429
|
+
```javascript
|
|
430
|
+
app.get('/moderator', validateSession, checkRolePermission('SuperAdmin'), (req, res) => {
|
|
431
|
+
res.send('Moderator panel');
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
### `authenticate(token)`
|
|
438
|
+
|
|
439
|
+
API authentication middleware for server-to-server communication.
|
|
440
|
+
|
|
441
|
+
**Parameters:**
|
|
442
|
+
- `token` (string) - Secret token for authentication
|
|
443
|
+
|
|
444
|
+
**Usage:**
|
|
445
|
+
```javascript
|
|
446
|
+
import { authenticate } from 'mbkauthe';
|
|
447
|
+
|
|
448
|
+
app.post('/api/data', authenticate(process.env.API_TOKEN), (req, res) => {
|
|
449
|
+
res.json({ data: 'Protected API data' });
|
|
450
|
+
});
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Headers Required:**
|
|
454
|
+
```
|
|
455
|
+
Authorization: your-secret-token
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Behavior:**
|
|
459
|
+
- Checks `Authorization` header
|
|
460
|
+
- Compares with provided token
|
|
461
|
+
- Returns 401 if token doesn't match
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
### `authapi(requiredRole)`
|
|
466
|
+
|
|
467
|
+
Advanced API authentication with role-based access control.
|
|
468
|
+
|
|
469
|
+
**Parameters:**
|
|
470
|
+
- `requiredRole` (array, optional) - Array of allowed roles
|
|
471
|
+
|
|
472
|
+
**Usage:**
|
|
473
|
+
```javascript
|
|
474
|
+
import { authapi } from 'mbkauthe';
|
|
475
|
+
|
|
476
|
+
// Any authenticated API user
|
|
477
|
+
app.get('/api/data', authapi(), (req, res) => {
|
|
478
|
+
console.log(req.user); // { username, UserName, role, Role }
|
|
479
|
+
res.json({ data: 'API data' });
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
// Only SuperAdmin via API
|
|
483
|
+
app.post('/api/admin/action', authapi(['SuperAdmin']), (req, res) => {
|
|
484
|
+
res.json({ success: true });
|
|
485
|
+
});
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Headers Required:**
|
|
489
|
+
```
|
|
490
|
+
Authorization: user-api-key-64-char-hex
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Behavior:**
|
|
494
|
+
- Validates API key from `Authorization` header
|
|
495
|
+
- Looks up user associated with API key
|
|
496
|
+
- Checks if user account is active
|
|
497
|
+
- Verifies user role if `requiredRole` is specified
|
|
498
|
+
- Blocks demo users from accessing endpoints
|
|
499
|
+
- Populates `req.user` with user information
|
|
500
|
+
- Returns 401 if unauthorized, 403 if insufficient permissions
|
|
501
|
+
|
|
502
|
+
**req.user Object:**
|
|
503
|
+
```javascript
|
|
504
|
+
req.user = {
|
|
505
|
+
username: "john.doe",
|
|
506
|
+
UserName: "john.doe",
|
|
507
|
+
role: "NormalUser",
|
|
508
|
+
Role: "NormalUser"
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**Database Requirement:**
|
|
513
|
+
Requires `UserAuthApiKey` table:
|
|
514
|
+
```sql
|
|
515
|
+
CREATE TABLE "UserAuthApiKey" (
|
|
516
|
+
username VARCHAR(50) PRIMARY KEY REFERENCES "Users"("UserName"),
|
|
517
|
+
"key" VARCHAR(64) UNIQUE NOT NULL
|
|
518
|
+
);
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
## Error Codes
|
|
524
|
+
|
|
525
|
+
### HTTP Status Codes
|
|
526
|
+
|
|
527
|
+
| Code | Meaning | Usage |
|
|
528
|
+
|------|---------|-------|
|
|
529
|
+
| 200 | OK | Successful request |
|
|
530
|
+
| 400 | Bad Request | Invalid input data |
|
|
531
|
+
| 401 | Unauthorized | Authentication required or failed |
|
|
532
|
+
| 403 | Forbidden | Insufficient permissions |
|
|
533
|
+
| 404 | Not Found | Resource not found |
|
|
534
|
+
| 429 | Too Many Requests | Rate limit exceeded |
|
|
535
|
+
| 500 | Internal Server Error | Server-side error |
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## Code Examples
|
|
540
|
+
|
|
541
|
+
### Basic Integration
|
|
542
|
+
|
|
543
|
+
```javascript
|
|
544
|
+
import express from 'express';
|
|
545
|
+
import mbkauthe, { validateSession } from 'mbkauthe';
|
|
546
|
+
import dotenv from 'dotenv';
|
|
547
|
+
|
|
548
|
+
dotenv.config();
|
|
549
|
+
|
|
550
|
+
// Configure MBKAuthe
|
|
551
|
+
process.env.mbkautheVar = JSON.stringify({
|
|
552
|
+
APP_NAME: process.env.APP_NAME,
|
|
553
|
+
SESSION_SECRET_KEY: process.env.SESSION_SECRET_KEY,
|
|
554
|
+
IS_DEPLOYED: process.env.IS_DEPLOYED,
|
|
555
|
+
DOMAIN: process.env.DOMAIN,
|
|
556
|
+
LOGIN_DB: process.env.LOGIN_DB,
|
|
557
|
+
MBKAUTH_TWO_FA_ENABLE: process.env.MBKAUTH_TWO_FA_ENABLE,
|
|
558
|
+
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 2,
|
|
559
|
+
loginRedirectURL: '/dashboard'
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
const app = express();
|
|
563
|
+
|
|
564
|
+
// Mount MBKAuthe routes
|
|
565
|
+
app.use(mbkauthe);
|
|
566
|
+
|
|
567
|
+
// Protected route
|
|
568
|
+
app.get('/dashboard', validateSession, (req, res) => {
|
|
569
|
+
res.send(`Welcome ${req.session.user.username}!`);
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
app.listen(3000, () => {
|
|
573
|
+
console.log('Server running on http://localhost:3000');
|
|
574
|
+
});
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
### Role-Based Access Control
|
|
580
|
+
|
|
581
|
+
```javascript
|
|
582
|
+
import { validateSession, checkRolePermission, validateSessionAndRole } from 'mbkauthe';
|
|
583
|
+
|
|
584
|
+
// Method 1: Separate middleware
|
|
585
|
+
app.get('/admin',
|
|
586
|
+
validateSession,
|
|
587
|
+
checkRolePermission('SuperAdmin'),
|
|
588
|
+
(req, res) => {
|
|
589
|
+
res.send('Admin panel');
|
|
590
|
+
}
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
// Method 2: Combined middleware
|
|
594
|
+
app.get('/admin',
|
|
595
|
+
validateSessionAndRole('SuperAdmin'),
|
|
596
|
+
(req, res) => {
|
|
597
|
+
res.send('Admin panel');
|
|
598
|
+
}
|
|
599
|
+
);
|
|
600
|
+
|
|
601
|
+
// Allow any role except Guest
|
|
602
|
+
app.get('/content',
|
|
603
|
+
validateSession,
|
|
604
|
+
checkRolePermission('Any', 'Guest'),
|
|
605
|
+
(req, res) => {
|
|
606
|
+
res.send('Content for registered users');
|
|
607
|
+
}
|
|
608
|
+
);
|
|
609
|
+
|
|
610
|
+
// Multiple roles (using separate middleware)
|
|
611
|
+
app.get('/moderator',
|
|
612
|
+
validateSession,
|
|
613
|
+
(req, res, next) => {
|
|
614
|
+
if (['SuperAdmin', 'NormalUser'].includes(req.session.user.role)) {
|
|
615
|
+
next();
|
|
616
|
+
} else {
|
|
617
|
+
res.status(403).send('Access denied');
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
(req, res) => {
|
|
621
|
+
res.send('Moderator panel');
|
|
622
|
+
}
|
|
623
|
+
);
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
### API Authentication
|
|
629
|
+
|
|
630
|
+
```javascript
|
|
631
|
+
import { authenticate, authapi } from 'mbkauthe';
|
|
632
|
+
|
|
633
|
+
// Simple token authentication
|
|
634
|
+
app.post('/api/webhook',
|
|
635
|
+
authenticate(process.env.WEBHOOK_SECRET),
|
|
636
|
+
(req, res) => {
|
|
637
|
+
// Process webhook
|
|
638
|
+
res.json({ received: true });
|
|
639
|
+
}
|
|
640
|
+
);
|
|
641
|
+
|
|
642
|
+
// API key with user validation
|
|
643
|
+
app.get('/api/user/profile', authapi(), async (req, res) => {
|
|
644
|
+
const { username } = req.user;
|
|
645
|
+
|
|
646
|
+
// Fetch user profile
|
|
647
|
+
const profile = await getUserProfile(username);
|
|
648
|
+
|
|
649
|
+
res.json({ success: true, profile });
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
// API key with role requirement
|
|
653
|
+
app.delete('/api/admin/users/:id',
|
|
654
|
+
authapi(['SuperAdmin']),
|
|
655
|
+
async (req, res) => {
|
|
656
|
+
await deleteUser(req.params.id);
|
|
657
|
+
res.json({ success: true });
|
|
658
|
+
}
|
|
659
|
+
);
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
|
|
664
|
+
### Client-Side Login
|
|
665
|
+
|
|
666
|
+
```javascript
|
|
667
|
+
// Login form submission
|
|
668
|
+
document.getElementById('loginForm').addEventListener('submit', async (e) => {
|
|
669
|
+
e.preventDefault();
|
|
670
|
+
|
|
671
|
+
const username = document.getElementById('username').value;
|
|
672
|
+
const password = document.getElementById('password').value;
|
|
673
|
+
|
|
674
|
+
try {
|
|
675
|
+
const response = await fetch('/mbkauthe/api/login', {
|
|
676
|
+
method: 'POST',
|
|
677
|
+
headers: {
|
|
678
|
+
'Content-Type': 'application/json',
|
|
679
|
+
},
|
|
680
|
+
body: JSON.stringify({ username, password })
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
const data = await response.json();
|
|
684
|
+
|
|
685
|
+
if (data.success) {
|
|
686
|
+
if (data.twoFactorRequired) {
|
|
687
|
+
// Redirect to 2FA page
|
|
688
|
+
window.location.href = '/mbkauthe/2fa';
|
|
689
|
+
} else {
|
|
690
|
+
// Login successful, redirect
|
|
691
|
+
window.location.href = data.redirectUrl || '/dashboard';
|
|
692
|
+
}
|
|
693
|
+
} else {
|
|
694
|
+
alert(data.message || 'Login failed');
|
|
695
|
+
}
|
|
696
|
+
} catch (error) {
|
|
697
|
+
console.error('Login error:', error);
|
|
698
|
+
alert('An error occurred during login');
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
---
|
|
704
|
+
|
|
705
|
+
### Client-Side Logout
|
|
706
|
+
|
|
707
|
+
```javascript
|
|
708
|
+
async function logout() {
|
|
709
|
+
// Get CSRF token from page
|
|
710
|
+
const csrfToken = document.querySelector('[name="_csrf"]').value;
|
|
711
|
+
|
|
712
|
+
try {
|
|
713
|
+
const response = await fetch('/mbkauthe/api/logout', {
|
|
714
|
+
method: 'POST',
|
|
715
|
+
headers: {
|
|
716
|
+
'Content-Type': 'application/json',
|
|
717
|
+
},
|
|
718
|
+
body: JSON.stringify({ _csrf: csrfToken })
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
const data = await response.json();
|
|
722
|
+
|
|
723
|
+
if (data.success) {
|
|
724
|
+
window.location.href = '/mbkauthe/login';
|
|
725
|
+
} else {
|
|
726
|
+
alert('Logout failed: ' + data.message);
|
|
727
|
+
}
|
|
728
|
+
} catch (error) {
|
|
729
|
+
console.error('Logout error:', error);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
---
|
|
735
|
+
|
|
736
|
+
### Database Access
|
|
737
|
+
|
|
738
|
+
```javascript
|
|
739
|
+
import { dblogin } from 'mbkauthe';
|
|
740
|
+
|
|
741
|
+
// Custom query using the database pool
|
|
742
|
+
app.get('/api/users', validateSession, checkRolePermission('SuperAdmin'), async (req, res) => {
|
|
743
|
+
try {
|
|
744
|
+
const result = await dblogin.query(
|
|
745
|
+
'SELECT id, "UserName", "Role", "Active" FROM "Users" ORDER BY id'
|
|
746
|
+
);
|
|
747
|
+
|
|
748
|
+
res.json({
|
|
749
|
+
success: true,
|
|
750
|
+
users: result.rows
|
|
751
|
+
});
|
|
752
|
+
} catch (error) {
|
|
753
|
+
console.error('Database error:', error);
|
|
754
|
+
res.status(500).json({
|
|
755
|
+
success: false,
|
|
756
|
+
message: 'Internal Server Error'
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
### Error Handling
|
|
765
|
+
|
|
766
|
+
```javascript
|
|
767
|
+
// Custom error handler
|
|
768
|
+
app.use((err, req, res, next) => {
|
|
769
|
+
console.error('Error:', err);
|
|
770
|
+
|
|
771
|
+
if (err.code === 'EBADCSRFTOKEN') {
|
|
772
|
+
return res.status(403).json({
|
|
773
|
+
success: false,
|
|
774
|
+
message: 'Invalid CSRF token'
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
res.status(500).json({
|
|
779
|
+
success: false,
|
|
780
|
+
message: 'Internal Server Error'
|
|
781
|
+
});
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
// 404 handler
|
|
785
|
+
app.use((req, res) => {
|
|
786
|
+
res.status(404).render('Error/dError.handlebars', {
|
|
787
|
+
layout: false,
|
|
788
|
+
code: 404,
|
|
789
|
+
error: 'Not Found',
|
|
790
|
+
message: 'The requested page was not found.',
|
|
791
|
+
pagename: 'Home',
|
|
792
|
+
page: '/',
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
## Security Best Practices
|
|
800
|
+
|
|
801
|
+
1. **Always use HTTPS in production** - Set `IS_DEPLOYED=true` and ensure your server uses SSL/TLS
|
|
802
|
+
2. **Keep SESSION_SECRET_KEY secure** - Use a strong, randomly generated key
|
|
803
|
+
3. **Enable 2FA for sensitive applications** - Set `MBKAUTH_TWO_FA_ENABLE=true`
|
|
804
|
+
4. **Validate all user input** - Never trust client-side data
|
|
805
|
+
5. **Use rate limiting** - Already implemented for authentication endpoints
|
|
806
|
+
6. **Keep dependencies updated** - Regularly update npm packages
|
|
807
|
+
7. **Monitor for security vulnerabilities** - Use `npm audit`
|
|
808
|
+
8. **Use prepared statements** - Prevent SQL injection (already implemented)
|
|
809
|
+
9. **Implement proper logging** - Track authentication events
|
|
810
|
+
10. **Regular security audits** - Review code and configurations
|
|
811
|
+
|
|
812
|
+
---
|
|
813
|
+
|
|
814
|
+
## Rate Limits
|
|
815
|
+
|
|
816
|
+
| Endpoint | Limit | Window |
|
|
817
|
+
|----------|-------|--------|
|
|
818
|
+
| `/mbkauthe/api/login` | 8 requests | 1 minute |
|
|
819
|
+
| `/mbkauthe/api/logout` | 10 requests | 1 minute |
|
|
820
|
+
| `/mbkauthe/api/verify-2fa` | 5 requests | 1 minute |
|
|
821
|
+
| `/mbkauthe/login` | 8 requests | 1 minute |
|
|
822
|
+
| `/mbkauthe/info` | 8 requests | 1 minute |
|
|
823
|
+
|
|
824
|
+
Rate limits are applied per IP address.
|
|
825
|
+
|
|
826
|
+
---
|
|
827
|
+
|
|
828
|
+
## Support
|
|
829
|
+
|
|
830
|
+
For issues, questions, or contributions:
|
|
831
|
+
|
|
832
|
+
- **GitHub Issues:** [https://github.com/MIbnEKhalid/mbkauthe/issues](https://github.com/MIbnEKhalid/mbkauthe/issues)
|
|
833
|
+
- **Email:** support@mbktechstudio.com
|
|
834
|
+
- **Documentation:** [https://github.com/MIbnEKhalid/mbkauthe](https://github.com/MIbnEKhalid/mbkauthe)
|
|
835
|
+
|
|
836
|
+
---
|
|
837
|
+
|
|
838
|
+
**Last Updated:** November 17, 2025
|
|
839
|
+
**Version:** 1.4.1
|
|
840
|
+
|
|
841
|
+
[← Back to README](../README.md)
|