mbkauthe 5.0.0 → 5.0.2
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/LICENSE +161 -335
- package/README.md +98 -112
- package/docs/README.md +33 -0
- package/docs/STYLE.md +40 -0
- package/docs/diagrams/auth-processes.mmd +80 -0
- package/docs/{env.md → guides/configuration.md} +2 -1
- package/docs/{db.md → guides/database.md} +3 -1
- package/docs/images/auth-processes.svg +1 -0
- package/docs/reference/api/authentication.md +105 -0
- package/docs/{api.md → reference/api/endpoints.md} +2 -683
- package/docs/reference/api/examples.md +251 -0
- package/docs/reference/api/middleware.md +239 -0
- package/docs/reference/api/operations.md +52 -0
- package/docs/reference/api.md +19 -0
- package/docs/{error-messages.md → reference/error-codes.md} +2 -0
- package/lib/createTable.js +2 -2
- package/package.json +4 -3
- package/docs/auth-processes.mmd +0 -71
- package/docs/images/auth-process.svg +0 -1
- /package/docs/{auth-flows.mmd → diagrams/auth-flows.mmd} +0 -0
- /package/docs/{db.sql → schema/db.sql} +0 -0
|
@@ -1,127 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Endpoints
|
|
2
2
|
|
|
3
|
-
[
|
|
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
|
-
- [Public Endpoints](#public-endpoints)
|
|
15
|
-
- [Protected Endpoints](#protected-endpoints)
|
|
16
|
-
- [OAuth Endpoints](#oauth-endpoints)
|
|
17
|
-
- [Information Endpoints](#information-endpoints)
|
|
18
|
-
- [Diagnostics (Dev Only)](#diagnostics-dev-only)
|
|
19
|
-
- [Additional Endpoints](#additional-endpoints)
|
|
20
|
-
- [Middleware Reference](#middleware-reference)
|
|
21
|
-
- [Code Examples](#code-examples)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Authentication
|
|
26
|
-
|
|
27
|
-
MBKAuthe supports two authentication methods:
|
|
28
|
-
|
|
29
|
-
1. **Session-based Authentication** - Cookie-based sessions for web applications
|
|
30
|
-
2. **Token-based Authentication** - Persistent API keys for server-to-server communication
|
|
31
|
-
|
|
32
|
-
### Token-based Authentication
|
|
33
|
-
|
|
34
|
-
For API clients and external services, use a Bearer token in the `Authorization` header.
|
|
35
|
-
|
|
36
|
-
**Header Format:**
|
|
37
|
-
```
|
|
38
|
-
Authorization: Bearer <your_api_token>
|
|
39
|
-
```
|
|
40
|
-
*Token format: `mbk_` followed by 64 hexadecimal characters.*
|
|
41
|
-
|
|
42
|
-
**Behavior:**
|
|
43
|
-
- **Stateless:** Validates against the `ApiTokens` table on every request.
|
|
44
|
-
- **Expiration:** Tokens can have an optional expiration date.
|
|
45
|
-
- **Permissions:** API tokens inherit the permissions of the user who created them.
|
|
46
|
-
- **Scopes:** Tokens have a scope (`read-only` or `write`) that controls which HTTP methods are allowed:
|
|
47
|
-
- `read-only`: Only GET, HEAD, and OPTIONS requests (safe, read-only operations)
|
|
48
|
-
- `write`: All HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
|
|
49
|
-
- **Usage Tracking:** The system updates the `LastUsed` timestamp on every successful request.
|
|
50
|
-
|
|
51
|
-
**Errors:**
|
|
52
|
-
- `401 Unauthorized` (Code 1005: `INVALID_AUTH_TOKEN`): Token is malformed or not found.
|
|
53
|
-
- `401 Unauthorized` (Code 1006: `API_TOKEN_EXPIRED`): Token exists but has passed its expiration date.
|
|
54
|
-
- `403 Forbidden` (Code 1007: `TOKEN_SCOPE_INSUFFICIENT`): Token scope doesn't allow this HTTP method.
|
|
55
|
-
|
|
56
|
-
**Example Usage:**
|
|
57
|
-
|
|
58
|
-
**1. Backend Implementation (Express):**
|
|
59
|
-
|
|
60
|
-
Even when using API tokens, the `validateSession`/`sessVal` middleware hydrates `req.session.user` for consistency, allowing you to use the same route logic for both browser and API clients.
|
|
61
|
-
|
|
62
|
-
```javascript
|
|
63
|
-
import { sessVal } from 'mbkauthe';
|
|
64
|
-
|
|
65
|
-
app.get('/api/protected-resource', sessVal, (req, res) => {
|
|
66
|
-
// Access user info populated from the token
|
|
67
|
-
const user = req.session.user; // { id, username, role, ... }
|
|
68
|
-
|
|
69
|
-
res.json({
|
|
70
|
-
message: `Hello ${user.username}`,
|
|
71
|
-
role: user.role
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**2. Client Request Examples:**
|
|
77
|
-
|
|
78
|
-
*cURL:*
|
|
79
|
-
```bash
|
|
80
|
-
curl -X GET https://api.yourdomain.com/api/protected-resource \
|
|
81
|
-
-H "Authorization: Bearer mbk_7f83a92b1dc..."
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
*JavaScript (Fetch):*
|
|
85
|
-
```javascript
|
|
86
|
-
const response = await fetch('https://api.yourdomain.com/api/protected-resource', {
|
|
87
|
-
headers: {
|
|
88
|
-
'Authorization': 'Bearer mbk_7f83a92b1dc...'
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
const data = await response.json();
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Output:**
|
|
95
|
-
```json
|
|
96
|
-
{
|
|
97
|
-
"message": "Hello john.doe",
|
|
98
|
-
"role": "NormalUser"
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## Session Management
|
|
105
|
-
|
|
106
|
-
### Session Cookie
|
|
107
|
-
|
|
108
|
-
When a user logs in, MBKAuthe creates a session and sets the following cookies:
|
|
109
|
-
|
|
110
|
-
| Cookie Name | Description | HttpOnly | Secure | SameSite |
|
|
111
|
-
|------------|-------------|----------|--------|----------|
|
|
112
|
-
| `mbkauthe.sid` | Session identifier | ✓ | Auto* | lax |
|
|
113
|
-
| `sessionId` | Encrypted session token (AES-256-GCM). This cookie is encrypted and treated as an opaque value by clients; do not attempt to parse or rely on the raw cookie contents. Use server endpoints (e.g., `GET /mbkauthe/api/checkSession`, `POST /mbkauthe/api/checkSession` (body) or `POST /mbkauthe/api/verifySession`) to validate or query session information. | ✓ | Auto* | lax |
|
|
114
|
-
| `username` | Username | ✗ | Auto* | lax |
|
|
115
|
-
|
|
116
|
-
\* `secure` flag is automatically set to `true` in production when `IS_DEPLOYED=true`
|
|
117
|
-
|
|
118
|
-
### Session Lifetime
|
|
119
|
-
|
|
120
|
-
- Default: 2 days (configurable via `COOKIE_EXPIRE_TIME`)
|
|
121
|
-
- Application sessions are stored in the `Sessions` table in PostgreSQL
|
|
122
|
-
- Sessions persist across subdomains in production
|
|
123
|
-
|
|
124
|
-
---
|
|
3
|
+
[Back to API index](../api.md) | [Back to docs index](../../README.md) | [Back to project README](../../../README.md)
|
|
125
4
|
|
|
126
5
|
## API Endpoints
|
|
127
6
|
|
|
@@ -1247,563 +1126,3 @@ Both GitHub and Google OAuth implementations include:
|
|
|
1247
1126
|
|
|
1248
1127
|
---
|
|
1249
1128
|
|
|
1250
|
-
## Middleware Reference
|
|
1251
|
-
|
|
1252
|
-
### `validateSession`/`sessRole`
|
|
1253
|
-
|
|
1254
|
-
Validates that the user has an active session.
|
|
1255
|
-
|
|
1256
|
-
**Usage:**
|
|
1257
|
-
```javascript
|
|
1258
|
-
import { sessRole } from 'mbkauthe';
|
|
1259
|
-
|
|
1260
|
-
app.get('/protected', sessRole, (req, res) => {
|
|
1261
|
-
// User is authenticated
|
|
1262
|
-
const user = req.session.user;
|
|
1263
|
-
// user contains: { id, username, UserName, role, Role, sessionId }
|
|
1264
|
-
res.send(`Welcome ${user.username}!`);
|
|
1265
|
-
});
|
|
1266
|
-
```
|
|
1267
|
-
|
|
1268
|
-
**Behavior:**
|
|
1269
|
-
- Checks for active session in `req.session.user`
|
|
1270
|
-
- Attempts to restore session from `sessionId` cookie if session not found
|
|
1271
|
-
- Validates session against database
|
|
1272
|
-
- Checks if user account is still active
|
|
1273
|
-
- Verifies user is authorized for the current application
|
|
1274
|
-
- Redirects to login page if validation fails
|
|
1275
|
-
|
|
1276
|
-
**JSON vs HTML error responses:**
|
|
1277
|
-
|
|
1278
|
-
When `validateSession` fails, MBKAuthe will either render an HTML error/login page (browser flow) or return a JSON error response (API/AJAX flow). A request is treated as **JSON** when any of these are true:
|
|
1279
|
-
|
|
1280
|
-
- URL/path starts with `/mbkauthe/api/` or `/api/`
|
|
1281
|
-
- `X-Requested-With: XMLHttpRequest`
|
|
1282
|
-
- `Accept` indicates JSON (e.g., `application/json`) and does not explicitly prefer `text/html`
|
|
1283
|
-
- `User-Agent` matches a non-browser client (e.g., `curl`, `wget`, `Postman`, `Insomnia`)
|
|
1284
|
-
- `User-Agent: json` (explicitly forces JSON responses)
|
|
1285
|
-
|
|
1286
|
-
**Example (force JSON errors on a page route):**
|
|
1287
|
-
```bash
|
|
1288
|
-
curl -i -H "User-Agent: json" http://localhost:3000/mbkauthe/test
|
|
1289
|
-
```
|
|
1290
|
-
|
|
1291
|
-
### reloadSessionUser(req, res)
|
|
1292
|
-
|
|
1293
|
-
Use this helper when you need to refresh the values stored in `req.session.user` from the authoritative database record (for example, after a profile update that changes FullName, or when session expiration policies are updated).
|
|
1294
|
-
|
|
1295
|
-
- Behavior:
|
|
1296
|
-
- Validates the session against the database (sessionId, active)
|
|
1297
|
-
- Updates `req.session.user` fields: `username`, `role`, `allowedApps`, `fullname`
|
|
1298
|
-
- Uses cached `fullName` cookie if available; falls back to querying `profiledata`
|
|
1299
|
-
- Syncs `username`, `fullName`, and `sessionId` cookies for client display
|
|
1300
|
-
- If the session is invalid (sessionId mismatch, inactive account, or unauthorized), it destroys the session and clears cookies
|
|
1301
|
-
|
|
1302
|
-
- Returns: `Promise<boolean>` — `true` if session was refreshed and still valid, `false` if session was invalidated or reload failed.
|
|
1303
|
-
|
|
1304
|
-
- Example:
|
|
1305
|
-
```javascript
|
|
1306
|
-
import { reloadSessionUser } from 'mbkauthe';
|
|
1307
|
-
|
|
1308
|
-
// After updating profile data
|
|
1309
|
-
app.post('/mbkauthe/api/update-profile', sessRole, async (req, res) => {
|
|
1310
|
-
// ... update profiledata.FullName in DB ...
|
|
1311
|
-
const refreshed = await reloadSessionUser(req, res);
|
|
1312
|
-
if (!refreshed) {
|
|
1313
|
-
return res.status(401).json({ success: false, message: 'Session invalidated' });
|
|
1314
|
-
}
|
|
1315
|
-
res.json({ success: true, fullname: req.session.user.fullname });
|
|
1316
|
-
});
|
|
1317
|
-
```
|
|
1318
|
-
|
|
1319
|
-
**Session Object:**
|
|
1320
|
-
```javascript
|
|
1321
|
-
req.session.user = {
|
|
1322
|
-
id: 1, // User ID
|
|
1323
|
-
username: "john.doe", // Username (login name)
|
|
1324
|
-
fullname: "John Doe", // Optional display name fetched from profiledata
|
|
1325
|
-
role: "NormalUser", // User role
|
|
1326
|
-
sessionId: "abc123...", // 64-char hex session ID
|
|
1327
|
-
}
|
|
1328
|
-
```
|
|
1329
|
-
|
|
1330
|
-
**Session Cookie Sync:**
|
|
1331
|
-
- The middleware sets non-httpOnly cookies for client display:
|
|
1332
|
-
- `username` — the login username (exposed for UI)
|
|
1333
|
-
- `fullName` — the display name (falls back to username if not available)
|
|
1334
|
-
|
|
1335
|
-
These cookies allow front-end UI to display a friendly name without making extra requests to the server.
|
|
1336
|
-
---
|
|
1337
|
-
|
|
1338
|
-
### `checkRolePermission(requiredRole, notAllowed)`/`roleChk `
|
|
1339
|
-
|
|
1340
|
-
Checks if the authenticated user has the required role.
|
|
1341
|
-
|
|
1342
|
-
**Parameters:**
|
|
1343
|
-
- `requiredRole` (string) - Required role: `"SuperAdmin"`, `"NormalUser"`, `"Guest"`, `"member"`, or `"Any"`/`"any"`
|
|
1344
|
-
- `notAllowed` (string, optional) - Role that is explicitly not allowed
|
|
1345
|
-
|
|
1346
|
-
**Usage:**
|
|
1347
|
-
```javascript
|
|
1348
|
-
import { sessVal, roleChk } from 'mbkauthe';
|
|
1349
|
-
|
|
1350
|
-
// Only SuperAdmin can access
|
|
1351
|
-
app.get('/admin', sessVal, roleChk('SuperAdmin'), (req, res) => {
|
|
1352
|
-
res.send('Admin panel');
|
|
1353
|
-
});
|
|
1354
|
-
|
|
1355
|
-
// Any authenticated user except Guest
|
|
1356
|
-
app.get('/content', sessVal, roleChk('Any', 'Guest'), (req, res) => {
|
|
1357
|
-
res.send('Protected content');
|
|
1358
|
-
});
|
|
1359
|
-
```
|
|
1360
|
-
|
|
1361
|
-
**Behavior:**
|
|
1362
|
-
- Checks if user is authenticated first
|
|
1363
|
-
- Fetches user role from database
|
|
1364
|
-
- Returns 403 if user has `notAllowed` role
|
|
1365
|
-
- Returns 403 if user doesn't have `requiredRole` (unless role is "Any")
|
|
1366
|
-
- Calls `next()` if authorized
|
|
1367
|
-
|
|
1368
|
-
---
|
|
1369
|
-
|
|
1370
|
-
### `validateSessionAndRole(requiredRole, notAllowed)`/`sessRole`
|
|
1371
|
-
|
|
1372
|
-
Combined middleware for session validation and role checking.
|
|
1373
|
-
|
|
1374
|
-
**Parameters:**
|
|
1375
|
-
- `requiredRole` (string) - Required role
|
|
1376
|
-
- `notAllowed` (string, optional) - Role that is explicitly not allowed
|
|
1377
|
-
|
|
1378
|
-
**Usage:**
|
|
1379
|
-
```javascript
|
|
1380
|
-
import { sessRole, roleChk } from 'mbkauthe';
|
|
1381
|
-
|
|
1382
|
-
// Validate session AND check role in one middleware
|
|
1383
|
-
app.get('/moderator', sessRole('SuperAdmin'), (req, res) => {
|
|
1384
|
-
res.send('Moderator panel');
|
|
1385
|
-
});
|
|
1386
|
-
```
|
|
1387
|
-
|
|
1388
|
-
**Equivalent to:**
|
|
1389
|
-
```javascript
|
|
1390
|
-
app.get('/moderator', sessVal, roleChk('SuperAdmin'), (req, res) => {
|
|
1391
|
-
res.send('Moderator panel');
|
|
1392
|
-
});
|
|
1393
|
-
```
|
|
1394
|
-
|
|
1395
|
-
---
|
|
1396
|
-
|
|
1397
|
-
### Strict validation helpers
|
|
1398
|
-
|
|
1399
|
-
For endpoints that must reject API token-based authentication and only accept browser session cookies, MBKAuthe exposes two strict helpers:
|
|
1400
|
-
|
|
1401
|
-
- `strictValidateSession` — same as `validateSession`, but rejects requests that provide `Authorization` headers (API tokens) and returns `401` when a token is used.
|
|
1402
|
-
- `strictValidateSessionAndRole(requiredRole, notAllowed)` — combined helper that behaves like `validateSessionAndRole` but enforces strict (cookie-only) authentication.
|
|
1403
|
-
|
|
1404
|
-
**Usage examples:**
|
|
1405
|
-
```javascript
|
|
1406
|
-
import { strictValidateSession, strictValidateSessionAndRole } from 'mbkauthe';
|
|
1407
|
-
|
|
1408
|
-
// Accept only cookie sessions
|
|
1409
|
-
app.get('/sensitive', strictValidateSession, (req, res) => {
|
|
1410
|
-
res.send('Sensitive data');
|
|
1411
|
-
});
|
|
1412
|
-
|
|
1413
|
-
// Validate session AND role, using cookie-only authentication
|
|
1414
|
-
app.get('/admin', strictValidateSessionAndRole('SuperAdmin'), (req, res) => {
|
|
1415
|
-
res.send('Admin');
|
|
1416
|
-
});
|
|
1417
|
-
```
|
|
1418
|
-
|
|
1419
|
-
---
|
|
1420
|
-
|
|
1421
|
-
### Response Utilities
|
|
1422
|
-
|
|
1423
|
-
MBKAuthe exports small helpers to assist with page rendering and context:
|
|
1424
|
-
|
|
1425
|
-
- `getUserContext(req)` — returns a lightweight context object for templates: `{ userLoggedIn, isuserlogin, username, fullname, role, allowedApps }`.
|
|
1426
|
-
- `renderPage(req, res, fileLocation, layout = true, data = {})` — renders a template with the user/context merged into the data; returns a Promise and yields the typical Express `res.render` behavior.
|
|
1427
|
-
- `renderError(res, req, options)` — renders the standardized error page; note the signature is `(res, req, options)` and `options` follow the `ErrorRenderOptions` described in the types.
|
|
1428
|
-
|
|
1429
|
-
**Example:**
|
|
1430
|
-
|
|
1431
|
-
```javascript
|
|
1432
|
-
import { getUserContext, renderPage, renderError } from 'mbkauthe';
|
|
1433
|
-
|
|
1434
|
-
app.get('/dashboard', (req, res) => {
|
|
1435
|
-
const ctx = getUserContext(req);
|
|
1436
|
-
return renderPage(req, res, 'info', true, { greeting: 'Hello', ...ctx });
|
|
1437
|
-
});
|
|
1438
|
-
|
|
1439
|
-
app.get('/err', (req, res) => {
|
|
1440
|
-
return renderError(res, req, {
|
|
1441
|
-
layout: false,
|
|
1442
|
-
code: 500,
|
|
1443
|
-
error: "Internal Server Error",
|
|
1444
|
-
message: "Simulated 500 Error",
|
|
1445
|
-
details: "This is a simulated 500 error page for testing purposes.",
|
|
1446
|
-
pagename: "Home",
|
|
1447
|
-
page: "/mbkauthe/login",
|
|
1448
|
-
});
|
|
1449
|
-
});
|
|
1450
|
-
```
|
|
1451
|
-
|
|
1452
|
-
---
|
|
1453
|
-
|
|
1454
|
-
### `authenticate(token)`
|
|
1455
|
-
|
|
1456
|
-
API authentication middleware for server-to-server communication.
|
|
1457
|
-
|
|
1458
|
-
**Parameters:**
|
|
1459
|
-
- `token` (string) - Secret token for authentication
|
|
1460
|
-
|
|
1461
|
-
**Usage:**
|
|
1462
|
-
```javascript
|
|
1463
|
-
import { authenticate } from 'mbkauthe';
|
|
1464
|
-
|
|
1465
|
-
app.post('/api/data', authenticate(process.env.API_TOKEN), (req, res) => {
|
|
1466
|
-
res.json({ data: 'Protected API data' });
|
|
1467
|
-
});
|
|
1468
|
-
```
|
|
1469
|
-
|
|
1470
|
-
**Headers Required:**
|
|
1471
|
-
```
|
|
1472
|
-
Authorization: Bearer your-secret-token
|
|
1473
|
-
```
|
|
1474
|
-
|
|
1475
|
-
You can also send the raw token without the `Bearer` prefix.
|
|
1476
|
-
|
|
1477
|
-
**Behavior:**
|
|
1478
|
-
- Checks `Authorization` header
|
|
1479
|
-
- Extracts the token (strips optional `Bearer` prefix)
|
|
1480
|
-
- Compares the provided token to the expected token using a timing-safe SHA-256 hash comparison
|
|
1481
|
-
- Returns 401 if token doesn't match
|
|
1482
|
-
|
|
1483
|
-
---
|
|
1484
|
-
|
|
1485
|
-
## Error Codes
|
|
1486
|
-
|
|
1487
|
-
### HTTP Status Codes
|
|
1488
|
-
|
|
1489
|
-
| Code | Meaning | Usage |
|
|
1490
|
-
|------|---------|-------|
|
|
1491
|
-
| 200 | OK | Successful request |
|
|
1492
|
-
| 400 | Bad Request | Invalid input data |
|
|
1493
|
-
| 401 | Unauthorized | Authentication required or failed |
|
|
1494
|
-
| 403 | Forbidden | Insufficient permissions |
|
|
1495
|
-
| 404 | Not Found | Resource not found |
|
|
1496
|
-
| 429 | Too Many Requests | Rate limit exceeded |
|
|
1497
|
-
| 500 | Internal Server Error | Server-side error |
|
|
1498
|
-
|
|
1499
|
-
---
|
|
1500
|
-
|
|
1501
|
-
## Code Examples
|
|
1502
|
-
|
|
1503
|
-
### Basic Integration
|
|
1504
|
-
|
|
1505
|
-
```javascript
|
|
1506
|
-
import express from 'express';
|
|
1507
|
-
import mbkauthe, { validateSession } from 'mbkauthe';
|
|
1508
|
-
import dotenv from 'dotenv';
|
|
1509
|
-
|
|
1510
|
-
dotenv.config();
|
|
1511
|
-
|
|
1512
|
-
// Configure MBKAuthe
|
|
1513
|
-
process.env.mbkautheVar = JSON.stringify({
|
|
1514
|
-
APP_NAME: process.env.APP_NAME,
|
|
1515
|
-
SESSION_SECRET_KEY: process.env.SESSION_SECRET_KEY,
|
|
1516
|
-
IS_DEPLOYED: process.env.IS_DEPLOYED,
|
|
1517
|
-
DOMAIN: process.env.DOMAIN,
|
|
1518
|
-
LOGIN_DB: process.env.LOGIN_DB,
|
|
1519
|
-
MBKAUTH_TWO_FA_ENABLE: process.env.MBKAUTH_TWO_FA_ENABLE,
|
|
1520
|
-
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 2,
|
|
1521
|
-
loginRedirectURL: '/dashboard'
|
|
1522
|
-
});
|
|
1523
|
-
|
|
1524
|
-
const app = express();
|
|
1525
|
-
|
|
1526
|
-
// Mount MBKAuthe routes
|
|
1527
|
-
app.use(mbkauthe);
|
|
1528
|
-
|
|
1529
|
-
// Protected route
|
|
1530
|
-
app.get('/dashboard', sessVal, (req, res) => {
|
|
1531
|
-
res.send(`Welcome ${req.session.user.username}!`);
|
|
1532
|
-
});
|
|
1533
|
-
|
|
1534
|
-
app.listen(3000, () => {
|
|
1535
|
-
console.log('Server running on http://localhost:3000');
|
|
1536
|
-
});
|
|
1537
|
-
```
|
|
1538
|
-
|
|
1539
|
-
---
|
|
1540
|
-
|
|
1541
|
-
### Role-Based Access Control
|
|
1542
|
-
|
|
1543
|
-
```javascript
|
|
1544
|
-
import { sessVal, roleChk, sessRole } from 'mbkauthe';
|
|
1545
|
-
|
|
1546
|
-
// Method 1: Separate middleware
|
|
1547
|
-
app.get('/admin',
|
|
1548
|
-
sessVal,
|
|
1549
|
-
roleChk('SuperAdmin'),
|
|
1550
|
-
(req, res) => {
|
|
1551
|
-
res.send('Admin panel');
|
|
1552
|
-
}
|
|
1553
|
-
);
|
|
1554
|
-
|
|
1555
|
-
// Method 2: Combined middleware
|
|
1556
|
-
app.get('/admin',
|
|
1557
|
-
sessRole('SuperAdmin'),
|
|
1558
|
-
(req, res) => {
|
|
1559
|
-
res.send('Admin panel');
|
|
1560
|
-
}
|
|
1561
|
-
);
|
|
1562
|
-
|
|
1563
|
-
// Allow any role except Guest
|
|
1564
|
-
app.get('/content',
|
|
1565
|
-
sessVal,
|
|
1566
|
-
roleChk('Any', 'Guest'),
|
|
1567
|
-
(req, res) => {
|
|
1568
|
-
res.send('Content for registered users');
|
|
1569
|
-
}
|
|
1570
|
-
);
|
|
1571
|
-
|
|
1572
|
-
// Multiple roles (using separate middleware)
|
|
1573
|
-
app.get('/moderator',
|
|
1574
|
-
sessVal,
|
|
1575
|
-
(req, res, next) => {
|
|
1576
|
-
if (['SuperAdmin', 'NormalUser'].includes(req.session.user.role)) {
|
|
1577
|
-
next();
|
|
1578
|
-
} else {
|
|
1579
|
-
res.status(403).send('Access denied');
|
|
1580
|
-
}
|
|
1581
|
-
},
|
|
1582
|
-
(req, res) => {
|
|
1583
|
-
res.send('Moderator panel');
|
|
1584
|
-
}
|
|
1585
|
-
);
|
|
1586
|
-
```
|
|
1587
|
-
|
|
1588
|
-
---
|
|
1589
|
-
|
|
1590
|
-
### API Authentication
|
|
1591
|
-
|
|
1592
|
-
```javascript
|
|
1593
|
-
import { authenticate } from 'mbkauthe';
|
|
1594
|
-
|
|
1595
|
-
// Simple token authentication
|
|
1596
|
-
app.post('/api/webhook',
|
|
1597
|
-
authenticate(process.env.WEBHOOK_SECRET),
|
|
1598
|
-
(req, res) => {
|
|
1599
|
-
// Process webhook
|
|
1600
|
-
res.json({ received: true });
|
|
1601
|
-
}
|
|
1602
|
-
);
|
|
1603
|
-
|
|
1604
|
-
// Admin API with token authentication
|
|
1605
|
-
app.post('/api/admin/terminate-sessions',
|
|
1606
|
-
authenticate(process.env.MAIN_SECRET_TOKEN),
|
|
1607
|
-
async (req, res) => {
|
|
1608
|
-
// Terminate all sessions
|
|
1609
|
-
res.json({ success: true });
|
|
1610
|
-
}
|
|
1611
|
-
);
|
|
1612
|
-
|
|
1613
|
-
// Protected API endpoint (requires session)
|
|
1614
|
-
app.get('/api/user/profile',
|
|
1615
|
-
sessVal,
|
|
1616
|
-
async (req, res) => {
|
|
1617
|
-
const { username } = req.session.user;
|
|
1618
|
-
|
|
1619
|
-
// Fetch user profile
|
|
1620
|
-
const profile = await getUserProfile(username);
|
|
1621
|
-
|
|
1622
|
-
res.json({ success: true, profile });
|
|
1623
|
-
}
|
|
1624
|
-
);
|
|
1625
|
-
```
|
|
1626
|
-
|
|
1627
|
-
---
|
|
1628
|
-
|
|
1629
|
-
### Client-Side Login
|
|
1630
|
-
|
|
1631
|
-
```javascript
|
|
1632
|
-
// Login form submission
|
|
1633
|
-
document.getElementById('loginForm').addEventListener('submit', async (e) => {
|
|
1634
|
-
e.preventDefault();
|
|
1635
|
-
|
|
1636
|
-
const username = document.getElementById('username').value;
|
|
1637
|
-
const password = document.getElementById('password').value;
|
|
1638
|
-
|
|
1639
|
-
try {
|
|
1640
|
-
const response = await fetch('/mbkauthe/api/login', {
|
|
1641
|
-
method: 'POST',
|
|
1642
|
-
headers: {
|
|
1643
|
-
'Content-Type': 'application/json',
|
|
1644
|
-
},
|
|
1645
|
-
body: JSON.stringify({ username, password })
|
|
1646
|
-
});
|
|
1647
|
-
|
|
1648
|
-
const data = await response.json();
|
|
1649
|
-
|
|
1650
|
-
if (data.success) {
|
|
1651
|
-
if (data.twoFactorRequired) {
|
|
1652
|
-
// Redirect to 2FA page
|
|
1653
|
-
window.location.href = '/mbkauthe/2fa';
|
|
1654
|
-
} else {
|
|
1655
|
-
// Login successful, redirect
|
|
1656
|
-
window.location.href = data.redirectUrl || '/dashboard';
|
|
1657
|
-
}
|
|
1658
|
-
} else {
|
|
1659
|
-
alert(data.message || 'Login failed');
|
|
1660
|
-
}
|
|
1661
|
-
} catch (error) {
|
|
1662
|
-
console.error('Login error:', error);
|
|
1663
|
-
alert('An error occurred during login');
|
|
1664
|
-
}
|
|
1665
|
-
});
|
|
1666
|
-
```
|
|
1667
|
-
|
|
1668
|
-
---
|
|
1669
|
-
|
|
1670
|
-
### Client-Side Logout
|
|
1671
|
-
|
|
1672
|
-
```javascript
|
|
1673
|
-
async function logout() {
|
|
1674
|
-
// Get CSRF token from page
|
|
1675
|
-
const csrfToken = document.querySelector('[name="_csrf"]').value;
|
|
1676
|
-
|
|
1677
|
-
try {
|
|
1678
|
-
const response = await fetch('/mbkauthe/api/logout', {
|
|
1679
|
-
method: 'POST',
|
|
1680
|
-
headers: {
|
|
1681
|
-
'Content-Type': 'application/json',
|
|
1682
|
-
},
|
|
1683
|
-
body: JSON.stringify({ _csrf: csrfToken })
|
|
1684
|
-
});
|
|
1685
|
-
|
|
1686
|
-
const data = await response.json();
|
|
1687
|
-
|
|
1688
|
-
if (data.success) {
|
|
1689
|
-
window.location.href = '/mbkauthe/login';
|
|
1690
|
-
} else {
|
|
1691
|
-
alert('Logout failed: ' + data.message);
|
|
1692
|
-
}
|
|
1693
|
-
} catch (error) {
|
|
1694
|
-
console.error('Logout error:', error);
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
```
|
|
1698
|
-
|
|
1699
|
-
---
|
|
1700
|
-
|
|
1701
|
-
### Database Access
|
|
1702
|
-
|
|
1703
|
-
```javascript
|
|
1704
|
-
import { dblogin } from 'mbkauthe';
|
|
1705
|
-
|
|
1706
|
-
// Custom query using the database pool
|
|
1707
|
-
app.get('/api/users', sessVal, roleChk('SuperAdmin'), async (req, res) => {
|
|
1708
|
-
try {
|
|
1709
|
-
const result = await dblogin.query(
|
|
1710
|
-
'SELECT id, "UserName", "Role", "Active" FROM "Users" ORDER BY id'
|
|
1711
|
-
);
|
|
1712
|
-
|
|
1713
|
-
res.json({
|
|
1714
|
-
success: true,
|
|
1715
|
-
users: result.rows
|
|
1716
|
-
});
|
|
1717
|
-
} catch (error) {
|
|
1718
|
-
console.error('Database error:', error);
|
|
1719
|
-
res.status(500).json({
|
|
1720
|
-
success: false,
|
|
1721
|
-
message: 'Internal Server Error'
|
|
1722
|
-
});
|
|
1723
|
-
}
|
|
1724
|
-
});
|
|
1725
|
-
```
|
|
1726
|
-
|
|
1727
|
-
---
|
|
1728
|
-
|
|
1729
|
-
### Error Handling
|
|
1730
|
-
|
|
1731
|
-
```javascript
|
|
1732
|
-
// Custom error handler
|
|
1733
|
-
app.use((err, req, res, next) => {
|
|
1734
|
-
console.error('Error:', err);
|
|
1735
|
-
|
|
1736
|
-
if (err.code === 'EBADCSRFTOKEN') {
|
|
1737
|
-
return res.status(403).json({
|
|
1738
|
-
success: false,
|
|
1739
|
-
message: 'Invalid CSRF token'
|
|
1740
|
-
});
|
|
1741
|
-
}
|
|
1742
|
-
|
|
1743
|
-
res.status(500).json({
|
|
1744
|
-
success: false,
|
|
1745
|
-
message: 'Internal Server Error'
|
|
1746
|
-
});
|
|
1747
|
-
});
|
|
1748
|
-
|
|
1749
|
-
// 404 handler
|
|
1750
|
-
app.use((req, res) => {
|
|
1751
|
-
res.status(404).render('Error/dError.handlebars', {
|
|
1752
|
-
layout: false,
|
|
1753
|
-
code: 404,
|
|
1754
|
-
error: 'Not Found',
|
|
1755
|
-
message: 'The requested page was not found.',
|
|
1756
|
-
pagename: 'Home',
|
|
1757
|
-
page: '/',
|
|
1758
|
-
});
|
|
1759
|
-
});
|
|
1760
|
-
```
|
|
1761
|
-
|
|
1762
|
-
---
|
|
1763
|
-
|
|
1764
|
-
## Security Best Practices
|
|
1765
|
-
|
|
1766
|
-
1. **Always use HTTPS in production** - Set `IS_DEPLOYED=true` and ensure your server uses SSL/TLS
|
|
1767
|
-
2. **Keep SESSION_SECRET_KEY secure** - Use a strong, randomly generated key
|
|
1768
|
-
3. **Enable 2FA for sensitive applications** - Set `MBKAUTH_TWO_FA_ENABLE=true`
|
|
1769
|
-
4. **Validate all user input** - Never trust client-side data
|
|
1770
|
-
5. **Use rate limiting** - Already implemented for authentication endpoints
|
|
1771
|
-
6. **Keep dependencies updated** - Regularly update npm packages
|
|
1772
|
-
7. **Monitor for security vulnerabilities** - Use `npm audit`
|
|
1773
|
-
8. **Use prepared statements** - Prevent SQL injection (already implemented)
|
|
1774
|
-
9. **Implement proper logging** - Track authentication events
|
|
1775
|
-
10. **Regular security audits** - Review code and configurations
|
|
1776
|
-
|
|
1777
|
-
---
|
|
1778
|
-
|
|
1779
|
-
## Rate Limits
|
|
1780
|
-
|
|
1781
|
-
| Endpoint | Limit | Window |
|
|
1782
|
-
|----------|-------|--------|
|
|
1783
|
-
| `/mbkauthe/api/login` | 8 requests | 1 minute |
|
|
1784
|
-
| `/mbkauthe/api/logout` | 10 requests | 1 minute |
|
|
1785
|
-
| `/mbkauthe/api/verify-2fa` | 5 requests | 1 minute |
|
|
1786
|
-
| `/mbkauthe/api/github/login` | 10 requests | 5 minutes |
|
|
1787
|
-
| `/mbkauthe/api/github/login/callback` | 10 requests | 5 minutes |
|
|
1788
|
-
| `/mbkauthe/login` | 8 requests | 1 minute |
|
|
1789
|
-
| `/mbkauthe/info` | 8 requests | 1 minute |
|
|
1790
|
-
| `/mbkauthe/test` | 8 requests | 1 minute |
|
|
1791
|
-
|
|
1792
|
-
Rate limits are applied per IP address. Logged-in users are exempt from some rate limits (e.g., login page rate limit).
|
|
1793
|
-
|
|
1794
|
-
---
|
|
1795
|
-
|
|
1796
|
-
## Support
|
|
1797
|
-
|
|
1798
|
-
For issues, questions, or contributions:
|
|
1799
|
-
|
|
1800
|
-
- **GitHub Issues:** [https://github.com/MIbnEKhalid/mbkauthe/issues](https://github.com/MIbnEKhalid/mbkauthe/issues)
|
|
1801
|
-
- **Email:** support@mbktech.org
|
|
1802
|
-
- **Documentation:** [https://github.com/MIbnEKhalid/mbkauthe](https://github.com/MIbnEKhalid/mbkauthe)
|
|
1803
|
-
|
|
1804
|
-
---
|
|
1805
|
-
|
|
1806
|
-
**Last Updated:** November 17, 2025
|
|
1807
|
-
**Version:** 1.4.2
|
|
1808
|
-
|
|
1809
|
-
[← Back to README](../README.md)
|