mbkauthe 2.1.0 → 2.2.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/.env.example +2 -2
- package/README.md +128 -7
- package/docs/api.md +48 -1
- package/docs/db.md +53 -15
- package/{env.md → docs/env.md} +76 -2
- package/index.js +9 -29
- package/lib/config.js +199 -0
- package/lib/main.js +234 -161
- package/lib/pool.js +1 -25
- package/lib/validateSessionAndRole.js +19 -131
- package/package.json +2 -2
- package/public/bg.webp +0 -0
- package/public/icon.ico +0 -0
- package/public/icon.svg +5 -0
- package/views/2fa.handlebars +21 -41
- package/views/Error/dError.handlebars +7 -35
- package/views/backgroundElements.handlebars +6 -0
- package/views/head.handlebars +14 -0
- package/views/header.handlebars +15 -0
- package/views/info.handlebars +8 -29
- package/views/loginmbkauthe.handlebars +5 -40
- package/views/sharedStyles.handlebars +112 -1
- package/views/versionInfo.handlebars +6 -0
- package/public/bg.avif +0 -0
package/.env.example
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
mbkautheVar={"APP_NAME":"mbkauthe","Main_SECRET_TOKEN": 123,"SESSION_SECRET_KEY":"123","IS_DEPLOYED":"true","LOGIN_DB":"postgres://","MBKAUTH_TWO_FA_ENABLE":"true","COOKIE_EXPIRE_TIME":2,"DOMAIN":"mbktech.org","loginRedirectURL":"/mbkauthe/test","GITHUB_LOGIN_ENABLED":"true","GITHUB_CLIENT_ID":"","GITHUB_CLIENT_SECRET":""}
|
|
1
|
+
mbkautheVar={"APP_NAME":"mbkauthe","Main_SECRET_TOKEN": 123,"SESSION_SECRET_KEY":"123","IS_DEPLOYED":"true","LOGIN_DB":"postgres://","MBKAUTH_TWO_FA_ENABLE":"true","COOKIE_EXPIRE_TIME":2,"DOMAIN":"mbktech.org","loginRedirectURL":"/mbkauthe/test","GITHUB_LOGIN_ENABLED":"true","GITHUB_CLIENT_ID":"","GITHUB_CLIENT_SECRET":"","DEVICE_TRUST_DURATION_DAYS":7}
|
|
2
2
|
|
|
3
|
-
# See env.md for more details
|
|
3
|
+
# See docs/env.md for more details
|
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
- 🔐 **Secure Authentication** - Password hashing with bcrypt
|
|
14
14
|
- 🔑 **Session Management** - PostgreSQL-backed session storage
|
|
15
15
|
- 📱 **Two-Factor Authentication (2FA)** - Optional TOTP-based 2FA with speakeasy
|
|
16
|
+
- 🔄 **GitHub OAuth Integration** - Login with GitHub accounts (passport-github2)
|
|
17
|
+
- 🖥️ **Trusted Devices** - Remember devices to skip 2FA on trusted devices
|
|
16
18
|
- 👥 **Role-Based Access Control** - SuperAdmin, NormalUser, and Guest roles
|
|
17
19
|
- 🎯 **Multi-Application Support** - Control user access across multiple apps
|
|
18
20
|
- 🛡️ **Security Features** - CSRF protection, rate limiting, secure cookies
|
|
@@ -37,6 +39,7 @@ Create a `.env` file in your project root:
|
|
|
37
39
|
# Application Configuration
|
|
38
40
|
APP_NAME=your-app-name
|
|
39
41
|
SESSION_SECRET_KEY=your-secure-random-secret-key
|
|
42
|
+
MAIN_SECRET_TOKEN=your-api-secret-token
|
|
40
43
|
IS_DEPLOYED=false
|
|
41
44
|
DOMAIN=localhost
|
|
42
45
|
|
|
@@ -46,9 +49,15 @@ LOGIN_DB=postgresql://username:password@localhost:5432/database_name
|
|
|
46
49
|
# Optional Features
|
|
47
50
|
MBKAUTH_TWO_FA_ENABLE=false
|
|
48
51
|
COOKIE_EXPIRE_TIME=2
|
|
52
|
+
DEVICE_TRUST_DURATION_DAYS=7
|
|
53
|
+
|
|
54
|
+
# GitHub OAuth (Optional)
|
|
55
|
+
GITHUB_LOGIN_ENABLED=false
|
|
56
|
+
GITHUB_CLIENT_ID=your-github-oauth-client-id
|
|
57
|
+
GITHUB_CLIENT_SECRET=your-github-oauth-client-secret
|
|
49
58
|
```
|
|
50
59
|
|
|
51
|
-
For detailed environment configuration, see [Environment Configuration Guide](env.md).
|
|
60
|
+
For detailed environment configuration, see [Environment Configuration Guide](docs/env.md).
|
|
52
61
|
|
|
53
62
|
### 2. Set Up Database
|
|
54
63
|
|
|
@@ -66,11 +75,15 @@ CREATE TABLE "Users" (
|
|
|
66
75
|
"Active" BOOLEAN DEFAULT FALSE,
|
|
67
76
|
"AllowedApps" JSONB DEFAULT '["mbkauthe"]',
|
|
68
77
|
"SessionId" VARCHAR(213),
|
|
69
|
-
"created_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
78
|
+
"created_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
79
|
+
"updated_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
80
|
+
"last_login" TIMESTAMP WITH TIME ZONE
|
|
70
81
|
);
|
|
71
82
|
|
|
72
83
|
-- Session table (created automatically by connect-pg-simple)
|
|
73
84
|
-- TwoFA table (optional, if 2FA is enabled)
|
|
85
|
+
-- TrustedDevices table (optional, for "Remember this device" feature)
|
|
86
|
+
-- user_github table (optional, for GitHub OAuth integration)
|
|
74
87
|
```
|
|
75
88
|
|
|
76
89
|
### 3. Integrate with Your Express App
|
|
@@ -87,11 +100,16 @@ dotenv.config();
|
|
|
87
100
|
process.env.mbkautheVar = JSON.stringify({
|
|
88
101
|
APP_NAME: process.env.APP_NAME,
|
|
89
102
|
SESSION_SECRET_KEY: process.env.SESSION_SECRET_KEY,
|
|
103
|
+
Main_SECRET_TOKEN: process.env.MAIN_SECRET_TOKEN,
|
|
90
104
|
IS_DEPLOYED: process.env.IS_DEPLOYED,
|
|
91
105
|
DOMAIN: process.env.DOMAIN,
|
|
92
106
|
LOGIN_DB: process.env.LOGIN_DB,
|
|
93
107
|
MBKAUTH_TWO_FA_ENABLE: process.env.MBKAUTH_TWO_FA_ENABLE,
|
|
94
108
|
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 2,
|
|
109
|
+
DEVICE_TRUST_DURATION_DAYS: process.env.DEVICE_TRUST_DURATION_DAYS || 7,
|
|
110
|
+
GITHUB_LOGIN_ENABLED: process.env.GITHUB_LOGIN_ENABLED,
|
|
111
|
+
GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID,
|
|
112
|
+
GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,
|
|
95
113
|
loginRedirectURL: '/dashboard' // Redirect after successful login
|
|
96
114
|
});
|
|
97
115
|
|
|
@@ -165,6 +183,8 @@ MBKAuth automatically adds these routes to your app:
|
|
|
165
183
|
- `POST /mbkauthe/api/logout` - Logout endpoint
|
|
166
184
|
- `GET /mbkauthe/2fa` - Two-factor authentication page (if enabled)
|
|
167
185
|
- `POST /mbkauthe/api/verify-2fa` - 2FA verification endpoint
|
|
186
|
+
- `GET /mbkauthe/api/github/login` - Initiate GitHub OAuth login
|
|
187
|
+
- `GET /mbkauthe/api/github/login/callback` - GitHub OAuth callback
|
|
168
188
|
- `GET /mbkauthe/info` - MBKAuth version and configuration info
|
|
169
189
|
- `POST /mbkauthe/api/terminateAllSessions` - Terminate all active sessions (authenticated)
|
|
170
190
|
|
|
@@ -174,6 +194,7 @@ MBKAuth automatically adds these routes to your app:
|
|
|
174
194
|
- **Login attempts**: 8 attempts per minute
|
|
175
195
|
- **Logout attempts**: 10 attempts per minute
|
|
176
196
|
- **2FA attempts**: 5 attempts per minute
|
|
197
|
+
- **GitHub OAuth attempts**: 10 attempts per 5 minutes
|
|
177
198
|
|
|
178
199
|
### CSRF Protection
|
|
179
200
|
All POST routes are protected with CSRF tokens. CSRF tokens are automatically included in rendered forms.
|
|
@@ -212,6 +233,103 @@ CREATE TABLE "TwoFA" (
|
|
|
212
233
|
);
|
|
213
234
|
```
|
|
214
235
|
|
|
236
|
+
## 🔄 GitHub OAuth Integration
|
|
237
|
+
|
|
238
|
+
### Overview
|
|
239
|
+
Users can log in using their GitHub accounts if they have previously linked their GitHub account to their MBKAuth account.
|
|
240
|
+
|
|
241
|
+
### Setup
|
|
242
|
+
|
|
243
|
+
1. **Create GitHub OAuth App**:
|
|
244
|
+
- Go to GitHub Settings > Developer settings > OAuth Apps
|
|
245
|
+
- Create a new OAuth App
|
|
246
|
+
- Set callback URL: `https://yourdomain.com/mbkauthe/api/github/login/callback`
|
|
247
|
+
- Copy Client ID and Client Secret
|
|
248
|
+
|
|
249
|
+
2. **Configure Environment**:
|
|
250
|
+
```env
|
|
251
|
+
GITHUB_LOGIN_ENABLED=true
|
|
252
|
+
GITHUB_CLIENT_ID=your_github_client_id
|
|
253
|
+
GITHUB_CLIENT_SECRET=your_github_client_secret
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
3. **Database Setup**:
|
|
257
|
+
```sql
|
|
258
|
+
CREATE TABLE user_github (
|
|
259
|
+
id SERIAL PRIMARY KEY,
|
|
260
|
+
user_name VARCHAR(50) REFERENCES "Users"("UserName"),
|
|
261
|
+
github_id VARCHAR(255) UNIQUE,
|
|
262
|
+
github_username VARCHAR(255),
|
|
263
|
+
access_token VARCHAR(255),
|
|
264
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
265
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
CREATE INDEX idx_user_github_github_id ON user_github (github_id);
|
|
269
|
+
CREATE INDEX idx_user_github_user_name ON user_github (user_name);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### How It Works
|
|
273
|
+
|
|
274
|
+
1. User clicks "Login with GitHub" on the login page
|
|
275
|
+
2. User authenticates with GitHub
|
|
276
|
+
3. System verifies the GitHub account is linked to an active user
|
|
277
|
+
4. If 2FA is enabled, user is prompted for 2FA code
|
|
278
|
+
5. Session is established upon successful authentication
|
|
279
|
+
|
|
280
|
+
### Routes
|
|
281
|
+
|
|
282
|
+
- `GET /mbkauthe/api/github/login` - Initiates GitHub OAuth flow
|
|
283
|
+
- `GET /mbkauthe/api/github/login/callback` - Handles OAuth callback
|
|
284
|
+
|
|
285
|
+
## 🖥️ Trusted Devices (Remember Device)
|
|
286
|
+
|
|
287
|
+
### Overview
|
|
288
|
+
The "Remember this device" feature allows users to skip 2FA verification on trusted devices for a configurable duration.
|
|
289
|
+
|
|
290
|
+
### Configuration
|
|
291
|
+
|
|
292
|
+
```env
|
|
293
|
+
# Duration in days before device trust expires (default: 7 days)
|
|
294
|
+
DEVICE_TRUST_DURATION_DAYS=7
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Database Setup
|
|
298
|
+
|
|
299
|
+
```sql
|
|
300
|
+
CREATE TABLE "TrustedDevices" (
|
|
301
|
+
"id" SERIAL PRIMARY KEY,
|
|
302
|
+
"UserName" VARCHAR(50) NOT NULL REFERENCES "Users"("UserName") ON DELETE CASCADE,
|
|
303
|
+
"DeviceToken" VARCHAR(64) UNIQUE NOT NULL,
|
|
304
|
+
"DeviceName" VARCHAR(255),
|
|
305
|
+
"UserAgent" TEXT,
|
|
306
|
+
"IpAddress" VARCHAR(45),
|
|
307
|
+
"CreatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
308
|
+
"ExpiresAt" TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
309
|
+
"LastUsed" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
CREATE INDEX idx_trusted_devices_token ON "TrustedDevices"("DeviceToken");
|
|
313
|
+
CREATE INDEX idx_trusted_devices_username ON "TrustedDevices"("UserName");
|
|
314
|
+
CREATE INDEX idx_trusted_devices_expires ON "TrustedDevices"("ExpiresAt");
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### How It Works
|
|
318
|
+
|
|
319
|
+
1. After successful login and 2FA verification, user can check "Remember this device"
|
|
320
|
+
2. A secure device token is generated and stored in cookies
|
|
321
|
+
3. On subsequent logins from the same device, 2FA is skipped
|
|
322
|
+
4. Device trust expires after configured duration
|
|
323
|
+
5. Users can manage trusted devices through their account settings
|
|
324
|
+
|
|
325
|
+
### Security Notes
|
|
326
|
+
|
|
327
|
+
- Device tokens are cryptographically secure (64-byte random tokens)
|
|
328
|
+
- Tokens automatically expire after the configured duration
|
|
329
|
+
- Last used timestamp is tracked for auditing
|
|
330
|
+
- IP address and user agent are stored for security monitoring
|
|
331
|
+
- Devices can be manually revoked by users
|
|
332
|
+
|
|
215
333
|
## 🎨 Customization
|
|
216
334
|
|
|
217
335
|
### Custom Login Redirect
|
|
@@ -266,19 +384,22 @@ Add `vercel.json`:
|
|
|
266
384
|
### Production Checklist
|
|
267
385
|
|
|
268
386
|
- [ ] Set `IS_DEPLOYED=true`
|
|
269
|
-
- [ ] Use a strong `SESSION_SECRET_KEY`
|
|
387
|
+
- [ ] Use a strong `SESSION_SECRET_KEY` and `Main_SECRET_TOKEN`
|
|
270
388
|
- [ ] Enable HTTPS
|
|
271
389
|
- [ ] Set correct `DOMAIN`
|
|
272
390
|
- [ ] Enable 2FA for sensitive applications
|
|
273
|
-
- [ ]
|
|
391
|
+
- [ ] Configure `DEVICE_TRUST_DURATION_DAYS` appropriately
|
|
392
|
+
- [ ] Set up GitHub OAuth if using GitHub login
|
|
393
|
+
- [ ] Use environment variables for all secrets
|
|
274
394
|
- [ ] Set appropriate `COOKIE_EXPIRE_TIME`
|
|
275
|
-
- [ ] Configure PostgreSQL with proper security
|
|
395
|
+
- [ ] Configure PostgreSQL with proper security and indexes
|
|
276
396
|
- [ ] Enable password hashing with bcrypt
|
|
397
|
+
- [ ] Regularly audit and clean up expired trusted devices
|
|
277
398
|
|
|
278
399
|
## 📚 Documentation
|
|
279
400
|
|
|
280
401
|
- [API Documentation](docs/api.md) - Complete API reference and examples
|
|
281
|
-
- [Environment Configuration Guide](env.md) - Environment variables and setup
|
|
402
|
+
- [Environment Configuration Guide](docs/env.md) - Environment variables and setup
|
|
282
403
|
- [Database Structure](docs/db.md) - Database schemas and tables
|
|
283
404
|
|
|
284
405
|
## 🔄 Version Check
|
|
@@ -302,7 +423,7 @@ This project is licensed under the Mozilla Public License 2.0 - see the [LICENSE
|
|
|
302
423
|
## 👨💻 Author
|
|
303
424
|
|
|
304
425
|
**Muhammad Bin Khalid**
|
|
305
|
-
Email: [support@
|
|
426
|
+
Email: [support@mbktech.org](support@mbktech.org) or [chmuhammadbinkhalid28@gmail.com](mailto:chmuhammadbinkhalid28@gmail.com)
|
|
306
427
|
GitHub: [@MIbnEKhalid](https://github.com/MIbnEKhalid)
|
|
307
428
|
|
|
308
429
|
## 🐛 Issues & Support
|
package/docs/api.md
CHANGED
|
@@ -364,6 +364,53 @@ Serves the client-side JavaScript file containing helper functions for authentic
|
|
|
364
364
|
- Forces page reload
|
|
365
365
|
|
|
366
366
|
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
#### `GET /icon.svg`
|
|
370
|
+
|
|
371
|
+
Serves the application's SVG icon file.
|
|
372
|
+
|
|
373
|
+
**Response:** SVG image file (Content-Type: image/svg+xml)
|
|
374
|
+
|
|
375
|
+
**Cache:** Cached for 1 year (max-age=31536000)
|
|
376
|
+
|
|
377
|
+
**Usage:**
|
|
378
|
+
```html
|
|
379
|
+
<img src="/icon.svg" alt="App Icon">
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
#### `GET /favicon.ico`
|
|
385
|
+
|
|
386
|
+
Serves the application's favicon.
|
|
387
|
+
|
|
388
|
+
**Aliases:** `/icon.ico`
|
|
389
|
+
|
|
390
|
+
**Response:** ICO image file (Content-Type: image/x-icon)
|
|
391
|
+
|
|
392
|
+
**Cache:** Cached for 1 year (max-age=31536000)
|
|
393
|
+
|
|
394
|
+
**Usage:**
|
|
395
|
+
```html
|
|
396
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
#### `GET /mbkauthe/bg.webp`
|
|
402
|
+
|
|
403
|
+
Serves the background image for authentication pages.
|
|
404
|
+
|
|
405
|
+
**Response:** WEBP image file (Content-Type: image/webp)
|
|
406
|
+
|
|
407
|
+
**Cache:** Cached for 1 year (max-age=31536000)
|
|
408
|
+
|
|
409
|
+
**Usage:**
|
|
410
|
+
```css
|
|
411
|
+
background-image: url('/mbkauthe/bg.webp');
|
|
412
|
+
```
|
|
413
|
+
|
|
367
414
|
---
|
|
368
415
|
|
|
369
416
|
#### `GET /mbkauthe/test`
|
|
@@ -896,7 +943,7 @@ Rate limits are applied per IP address.
|
|
|
896
943
|
For issues, questions, or contributions:
|
|
897
944
|
|
|
898
945
|
- **GitHub Issues:** [https://github.com/MIbnEKhalid/mbkauthe/issues](https://github.com/MIbnEKhalid/mbkauthe/issues)
|
|
899
|
-
- **Email:** support@
|
|
946
|
+
- **Email:** support@mbktech.org
|
|
900
947
|
- **Documentation:** [https://github.com/MIbnEKhalid/mbkauthe](https://github.com/MIbnEKhalid/mbkauthe)
|
|
901
948
|
|
|
902
949
|
---
|
package/docs/db.md
CHANGED
|
@@ -33,6 +33,10 @@ CREATE TABLE user_github (
|
|
|
33
33
|
created_at TimeStamp WITH TIME ZONE DEFAULT NOW(),
|
|
34
34
|
updated_at TimeStamp WITH TIME ZONE DEFAULT NOW()
|
|
35
35
|
);
|
|
36
|
+
|
|
37
|
+
-- Add indexes for performance optimization
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_user_github_github_id ON user_github (github_id);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_user_github_user_name ON user_github (user_name);
|
|
36
40
|
```
|
|
37
41
|
|
|
38
42
|
## How It Works
|
|
@@ -155,19 +159,18 @@ CREATE TABLE "Users" (
|
|
|
155
159
|
"HaveMailAccount" BOOLEAN DEFAULT FALSE,
|
|
156
160
|
"AllowedApps" JSONB DEFAULT '["mbkauthe", "portal"]',
|
|
157
161
|
"SessionId" VARCHAR(213),
|
|
158
|
-
"IsOnline" BOOLEAN DEFAULT FALSE,
|
|
159
162
|
"created_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
160
163
|
"updated_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
161
164
|
"last_login" TIMESTAMP WITH TIME ZONE
|
|
162
165
|
);
|
|
163
166
|
|
|
164
|
-
-- Add indexes for
|
|
165
|
-
CREATE INDEX IF NOT EXISTS
|
|
166
|
-
CREATE INDEX idx_users_username ON "Users"
|
|
167
|
-
CREATE INDEX
|
|
168
|
-
CREATE INDEX
|
|
169
|
-
CREATE INDEX
|
|
170
|
-
CREATE INDEX
|
|
167
|
+
-- Add indexes for performance optimization
|
|
168
|
+
CREATE INDEX IF NOT EXISTS idx_users_sessionid ON "Users" (LOWER("SessionId"));
|
|
169
|
+
CREATE INDEX IF NOT EXISTS idx_users_username ON "Users" ("UserName");
|
|
170
|
+
CREATE INDEX IF NOT EXISTS idx_users_active ON "Users" ("Active");
|
|
171
|
+
CREATE INDEX IF NOT EXISTS idx_users_role ON "Users" ("Role");
|
|
172
|
+
CREATE INDEX IF NOT EXISTS idx_users_last_login ON "Users" (last_login);
|
|
173
|
+
CREATE INDEX IF NOT EXISTS idx_users_id_sessionid_active_role ON "Users" ("id", LOWER("SessionId"), "Active", "Role");
|
|
171
174
|
```
|
|
172
175
|
|
|
173
176
|
### Session Table
|
|
@@ -184,14 +187,13 @@ CREATE TABLE "session" (
|
|
|
184
187
|
sid VARCHAR(33) PRIMARY KEY NOT NULL,
|
|
185
188
|
sess JSONB NOT NULL,
|
|
186
189
|
expire TimeStamp WITH TIME ZONE Not Null,
|
|
187
|
-
"UserName" VARCHAR(50) REFERENCES "Users"("UserName"),
|
|
188
190
|
last_activity TimeStamp WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
189
191
|
);
|
|
190
192
|
|
|
191
|
-
-- Add indexes for
|
|
192
|
-
CREATE INDEX idx_session_expire ON "session"
|
|
193
|
-
CREATE INDEX
|
|
194
|
-
CREATE INDEX
|
|
193
|
+
-- Add indexes for performance optimization
|
|
194
|
+
CREATE INDEX IF NOT EXISTS idx_session_expire ON "session" ("expire");
|
|
195
|
+
CREATE INDEX IF NOT EXISTS idx_session_last_activity ON "session" (last_activity);
|
|
196
|
+
CREATE INDEX IF NOT EXISTS idx_session_user_id ON "session" ((sess->'user'->>'id'));
|
|
195
197
|
```
|
|
196
198
|
|
|
197
199
|
### Two-Factor Authentication Table
|
|
@@ -208,9 +210,45 @@ CREATE TABLE "TwoFA" (
|
|
|
208
210
|
"UserName" VARCHAR(50) primary key REFERENCES "Users"("UserName"),
|
|
209
211
|
"TwoFAStatus" boolean NOT NULL,
|
|
210
212
|
"TwoFASecret" TEXT
|
|
211
|
-
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
-- Add indexes for performance optimization
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_twofa_username ON "TwoFA" ("UserName");
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_twofa_username_status ON "TwoFA" ("UserName", "TwoFAStatus");
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Trusted Devices Table (Remember 2FA Device)
|
|
221
|
+
|
|
222
|
+
- **Columns:**
|
|
223
|
+
|
|
224
|
+
- `id` (INTEGER, auto-increment, primary key): Unique identifier for each trusted device.
|
|
225
|
+
- `UserName` (VARCHAR): The username of the device owner (foreign key to Users).
|
|
226
|
+
- `DeviceToken` (VARCHAR): Unique token identifying the trusted device.
|
|
227
|
+
- `DeviceName` (VARCHAR): Optional friendly name for the device.
|
|
228
|
+
- `UserAgent` (TEXT): Browser/client user agent string.
|
|
229
|
+
- `IpAddress` (VARCHAR): IP address when device was trusted.
|
|
230
|
+
- `CreatedAt` (TIMESTAMP): When the device was first trusted.
|
|
231
|
+
- `ExpiresAt` (TIMESTAMP): When the device trust expires.
|
|
232
|
+
- `LastUsed` (TIMESTAMP): Last time this device was used for login.
|
|
233
|
+
|
|
234
|
+
- **Schema:**
|
|
235
|
+
```sql
|
|
236
|
+
CREATE TABLE "TrustedDevices" (
|
|
237
|
+
"id" SERIAL PRIMARY KEY,
|
|
238
|
+
"UserName" VARCHAR(50) NOT NULL REFERENCES "Users"("UserName") ON DELETE CASCADE,
|
|
239
|
+
"DeviceToken" VARCHAR(64) UNIQUE NOT NULL,
|
|
240
|
+
"DeviceName" VARCHAR(255),
|
|
241
|
+
"UserAgent" TEXT,
|
|
242
|
+
"IpAddress" VARCHAR(45),
|
|
243
|
+
"CreatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
244
|
+
"ExpiresAt" TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
245
|
+
"LastUsed" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
246
|
+
);
|
|
212
247
|
|
|
213
|
-
|
|
248
|
+
-- Add indexes for performance optimization
|
|
249
|
+
CREATE INDEX IF NOT EXISTS idx_trusted_devices_token ON "TrustedDevices"("DeviceToken");
|
|
250
|
+
CREATE INDEX IF NOT EXISTS idx_trusted_devices_username ON "TrustedDevices"("UserName");
|
|
251
|
+
CREATE INDEX IF NOT EXISTS idx_trusted_devices_expires ON "TrustedDevices"("ExpiresAt");
|
|
214
252
|
```
|
|
215
253
|
|
|
216
254
|
### Query to Add a User
|
package/{env.md → docs/env.md}
RENAMED
|
@@ -25,11 +25,22 @@ APP_NAME=mbkauthe
|
|
|
25
25
|
|
|
26
26
|
### Session Configuration
|
|
27
27
|
```env
|
|
28
|
+
Main_SECRET_TOKEN=your-secure-token-number
|
|
28
29
|
SESSION_SECRET_KEY=your-secure-random-key-here
|
|
29
30
|
IS_DEPLOYED=false
|
|
30
31
|
DOMAIN=localhost
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
#### Main_SECRET_TOKEN
|
|
35
|
+
**Description:** Primary authentication token for secure operations.
|
|
36
|
+
|
|
37
|
+
- **Security:** Use a secure numeric or alphanumeric token
|
|
38
|
+
- **Purpose:** Used for internal authentication and validation processes
|
|
39
|
+
- **Format:** Numeric or string value
|
|
40
|
+
- **Required:** Yes
|
|
41
|
+
|
|
42
|
+
**Example:** `Main_SECRET_TOKEN=123456789`
|
|
43
|
+
|
|
33
44
|
#### SESSION_SECRET_KEY
|
|
34
45
|
**Description:** Cryptographic key for session security.
|
|
35
46
|
|
|
@@ -115,6 +126,37 @@ MBKAUTH_TWO_FA_ENABLE=false
|
|
|
115
126
|
|
|
116
127
|
---
|
|
117
128
|
|
|
129
|
+
## 🔄 Redirect Configuration
|
|
130
|
+
|
|
131
|
+
### Login Redirect URL
|
|
132
|
+
```env
|
|
133
|
+
loginRedirectURL=/mbkauthe/test
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Description:** Specifies the URL path where users are redirected after successful authentication.
|
|
137
|
+
|
|
138
|
+
- **Purpose:** Controls post-login navigation flow
|
|
139
|
+
- **Format:** URL path (relative or absolute)
|
|
140
|
+
- **Default:** `/` (root path if not specified)
|
|
141
|
+
- **Required:** No (optional configuration)
|
|
142
|
+
|
|
143
|
+
**Examples:**
|
|
144
|
+
```env
|
|
145
|
+
# Redirect to dashboard
|
|
146
|
+
loginRedirectURL=/dashboard
|
|
147
|
+
|
|
148
|
+
# Redirect to specific app section
|
|
149
|
+
loginRedirectURL=/mbkauthe/test
|
|
150
|
+
|
|
151
|
+
# Redirect to home page
|
|
152
|
+
loginRedirectURL=/
|
|
153
|
+
|
|
154
|
+
# Redirect to external URL (if supported)
|
|
155
|
+
loginRedirectURL=https://example.com/app
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
118
160
|
## 🍪 Cookie Settings
|
|
119
161
|
|
|
120
162
|
### Cookie Expiration
|
|
@@ -132,8 +174,28 @@ COOKIE_EXPIRE_TIME=2
|
|
|
132
174
|
**Examples:**
|
|
133
175
|
```env
|
|
134
176
|
COOKIE_EXPIRE_TIME=1 # 1 day (high security)
|
|
135
|
-
COOKIE_EXPIRE_TIME=7 #
|
|
136
|
-
COOKIE_EXPIRE_TIME=30 #
|
|
177
|
+
COOKIE_EXPIRE_TIME=7 # 7 days (balanced)
|
|
178
|
+
COOKIE_EXPIRE_TIME=30 # 30 days (convenience)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Device Trust Duration
|
|
182
|
+
```env
|
|
183
|
+
DEVICE_TRUST_DURATION_DAYS=7
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Description:** Sets how long a device remains trusted after successful authentication.
|
|
187
|
+
|
|
188
|
+
- **Unit:** Days
|
|
189
|
+
- **Default:** `7` days
|
|
190
|
+
- **Purpose:** Controls device recognition and trust persistence
|
|
191
|
+
- **Range:** 1-365 days (recommended)
|
|
192
|
+
- **Behavior:** Trusted devices may skip certain authentication steps (like 2FA) during this period
|
|
193
|
+
|
|
194
|
+
**Examples:**
|
|
195
|
+
```env
|
|
196
|
+
DEVICE_TRUST_DURATION_DAYS=1 # 1 day (high security)
|
|
197
|
+
DEVICE_TRUST_DURATION_DAYS=7 # 1 week (balanced)
|
|
198
|
+
DEVICE_TRUST_DURATION_DAYS=30 # 30 days (convenience)
|
|
137
199
|
```
|
|
138
200
|
|
|
139
201
|
---
|
|
@@ -212,24 +274,36 @@ GITHUB_CLIENT_SECRET=your-github-client-secret
|
|
|
212
274
|
```env
|
|
213
275
|
# .env file for local development
|
|
214
276
|
APP_NAME=mbkauthe
|
|
277
|
+
Main_SECRET_TOKEN=dev-token-123
|
|
215
278
|
SESSION_SECRET_KEY=dev-secret-key-change-in-production
|
|
216
279
|
IS_DEPLOYED=false
|
|
217
280
|
DOMAIN=localhost
|
|
218
281
|
LOGIN_DB=postgresql://admin:password@localhost:5432/mbkauth_dev
|
|
219
282
|
MBKAUTH_TWO_FA_ENABLE=false
|
|
220
283
|
COOKIE_EXPIRE_TIME=7
|
|
284
|
+
DEVICE_TRUST_DURATION_DAYS=7
|
|
285
|
+
loginRedirectURL=/dashboard
|
|
286
|
+
GITHUB_LOGIN_ENABLED=false
|
|
287
|
+
GITHUB_CLIENT_ID=
|
|
288
|
+
GITHUB_CLIENT_SECRET=
|
|
221
289
|
```
|
|
222
290
|
|
|
223
291
|
### Production Environment
|
|
224
292
|
```env
|
|
225
293
|
# .env file for production deployment
|
|
226
294
|
APP_NAME=mbkauthe
|
|
295
|
+
Main_SECRET_TOKEN=your-secure-production-token
|
|
227
296
|
SESSION_SECRET_KEY=your-super-secure-production-key-here
|
|
228
297
|
IS_DEPLOYED=true
|
|
229
298
|
DOMAIN=yourdomain.com
|
|
230
299
|
LOGIN_DB=postgresql://dbuser:securepass@prod-db.example.com:5432/mbkauth_prod
|
|
231
300
|
MBKAUTH_TWO_FA_ENABLE=true
|
|
232
301
|
COOKIE_EXPIRE_TIME=2
|
|
302
|
+
DEVICE_TRUST_DURATION_DAYS=7
|
|
303
|
+
loginRedirectURL=/dashboard
|
|
304
|
+
GITHUB_LOGIN_ENABLED=false
|
|
305
|
+
GITHUB_CLIENT_ID=
|
|
306
|
+
GITHUB_CLIENT_SECRET=
|
|
233
307
|
```
|
|
234
308
|
|
|
235
309
|
---
|
package/index.js
CHANGED
|
@@ -2,36 +2,12 @@ import express from "express"; // Add this line
|
|
|
2
2
|
import router from "./lib/main.js";
|
|
3
3
|
import { getLatestVersion } from "./lib/main.js";
|
|
4
4
|
import { engine } from "express-handlebars";
|
|
5
|
-
import dotenv from "dotenv";
|
|
6
5
|
import path from "path";
|
|
7
6
|
import { fileURLToPath } from "url";
|
|
8
|
-
|
|
9
|
-
dotenv.config();
|
|
7
|
+
import { renderError, packageJson } from "./lib/config.js";
|
|
10
8
|
|
|
11
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
10
|
const __dirname = path.dirname(__filename);
|
|
13
|
-
let mbkautheVar;
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
mbkautheVar = JSON.parse(process.env.mbkautheVar);
|
|
17
|
-
} catch (error) {
|
|
18
|
-
throw new Error("Invalid JSON in process.env.mbkautheVar");
|
|
19
|
-
}
|
|
20
|
-
if (!mbkautheVar) {
|
|
21
|
-
throw new Error("mbkautheVar is not defined");
|
|
22
|
-
}
|
|
23
|
-
const requiredKeys = ["APP_NAME", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
|
|
24
|
-
requiredKeys.forEach(key => {
|
|
25
|
-
if (!mbkautheVar[key]) {
|
|
26
|
-
throw new Error(`mbkautheVar.${key} is required`);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
if (mbkautheVar.COOKIE_EXPIRE_TIME !== undefined) {
|
|
30
|
-
const expireTime = parseFloat(mbkautheVar.COOKIE_EXPIRE_TIME);
|
|
31
|
-
if (isNaN(expireTime) || expireTime <= 0) {
|
|
32
|
-
throw new Error("mbkautheVar.COOKIE_EXPIRE_TIME must be a valid positive number");
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
11
|
|
|
36
12
|
const app = express();
|
|
37
13
|
if (process.env.test === "dev") {
|
|
@@ -61,12 +37,18 @@ app.set("views", [
|
|
|
61
37
|
|
|
62
38
|
app.engine("handlebars", engine({
|
|
63
39
|
defaultLayout: false,
|
|
40
|
+
cache: true,
|
|
64
41
|
partialsDir: [
|
|
65
42
|
path.join(__dirname, "views"),
|
|
66
43
|
path.join(__dirname, "node_modules/mbkauthe/views"),
|
|
67
44
|
path.join(__dirname, "node_modules/mbkauthe/views/Error"),
|
|
68
45
|
],
|
|
69
46
|
helpers: {
|
|
47
|
+
concat: function (...args) {
|
|
48
|
+
// Remove the handlebars options object from args
|
|
49
|
+
args.pop();
|
|
50
|
+
return args.join('');
|
|
51
|
+
},
|
|
70
52
|
eq: function (a, b) {
|
|
71
53
|
return a === b;
|
|
72
54
|
},
|
|
@@ -92,14 +74,12 @@ app.engine("handlebars", engine({
|
|
|
92
74
|
|
|
93
75
|
app.set("view engine", "handlebars");
|
|
94
76
|
|
|
95
|
-
import { createRequire } from "module";
|
|
96
|
-
const require = createRequire(import.meta.url);
|
|
97
|
-
const packageJson = require("./package.json");
|
|
98
77
|
const latestVersion = await getLatestVersion();
|
|
99
78
|
if (latestVersion !== packageJson.version) {
|
|
100
79
|
console.warn(`[mbkauthe] Warning: The current version (${packageJson.version}) is not the latest version (${latestVersion}). Please update mbkauthe.`);
|
|
101
80
|
}
|
|
102
81
|
|
|
103
|
-
export { validateSession, checkRolePermission, validateSessionAndRole, authenticate
|
|
82
|
+
export { validateSession, checkRolePermission, validateSessionAndRole, authenticate } from "./lib/validateSessionAndRole.js";
|
|
83
|
+
export { renderError } from "./lib/config.js";
|
|
104
84
|
export { dblogin } from "./lib/pool.js";
|
|
105
85
|
export default router;
|