mbkauthe 1.0.7 → 1.0.8

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 CHANGED
@@ -1,5 +1,8 @@
1
1
  mbkautheVar='{
2
+ "APP_NAME": "MBKAUTH",
2
3
  "RECAPTCHA_SECRET_KEY": "your-recaptcha-secret-key",
4
+ "RECAPTCHA_Enabled": "f",
5
+ "BypassUsers": ["demo","user1"],
3
6
  "SESSION_SECRET_KEY": "your-session-secret-key",
4
7
  "IS_DEPLOYED": "true",
5
8
  "LOGIN_DB": "postgres://username:password@host:port/database",
package/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  - [Features](#features)
9
9
  - [Installation](#installation)
10
10
  - [Usage](#usage)
11
+ - [Implementation in a Project](#implementation-in-a-project)
11
12
  - [Basic Setup](#basic-setup)
12
13
  - [API Endpoints](#api-endpoints)
13
14
  - [Login](#login)
@@ -37,6 +38,18 @@ npm install mbkauthe
37
38
  ```
38
39
 
39
40
  ## Usage
41
+
42
+ ### Implementation in a Project
43
+
44
+ For a practical example of how to use this package, check out the [ProjectImplementation branch](https://github.com/MIbnEKhalid/mbkauthe/tree/ProjectImplementation) of the repository. This branch demonstrates the integration of the package, including a login page, a protected page, and logout functionality.
45
+
46
+ You can explore the functionality of `mbkAuthe` using the following demo account on [mbkauthe.mbktechstudio.com](https://mbkauthe.mbktechstudio.com):
47
+
48
+ - **Username**: `demo`
49
+ - **Password**: `demo`
50
+
51
+ This demo provides a hands-on experience with the authentication system, including login, session management, and other features.
52
+
40
53
  ### Basic Setup
41
54
  1. Import and configure the router in your Express application:
42
55
  ```javascript
@@ -51,17 +64,20 @@ app.listen(3000, () => {
51
64
  console.log("Server is running on port 3000");
52
65
  });
53
66
  ```
54
- 2. Ensure your ``.env` file is properly configured. Refer to the [Configuration Guide(env.md)](env.md) for details.
67
+ 2. Ensure your `.env` file is properly configured. Refer to the [Configuration Guide(env.md)](env.md) for details.
55
68
 
56
69
  Example `.env` file:
57
70
  ```code
58
71
  mbkautheVar='{
72
+ "APP_NAME": "MBKAUTH",
59
73
  "RECAPTCHA_SECRET_KEY": "your-recaptcha-secret-key",
74
+ "RECAPTCHA_Enabled": "false",
75
+ "BypassUsers": ["user1","user2"],
60
76
  "SESSION_SECRET_KEY": "your-session-secret-key",
61
77
  "IS_DEPLOYED": "true",
62
78
  "LOGIN_DB": "postgres://username:password@host:port/database",
63
79
  "MBKAUTH_TWO_FA_ENABLE": "false",
64
- "COOKIE_EXPIRE_TIME": 2,
80
+ "COOKIE_EXPIRE_TIME": "1",
65
81
  "DOMAIN": "yourdomain.com"
66
82
  }'
67
83
  ```
package/docs/db.md CHANGED
@@ -22,6 +22,7 @@
22
22
  - `HaveMailAccount` (BOOLEAN)(optional): Indicates if the user has a linked mail account.
23
23
  - `SessionId` (TEXT): The session ID associated with the user.
24
24
  - `GuestRole` (JSONB): Stores additional guest-specific role information in binary JSON format.
25
+ - `AllowedApps`(JSONB):
25
26
 
26
27
  - **Schema:**
27
28
  ```sql
@@ -34,6 +35,7 @@
34
35
  "HaveMailAccount" BOOLEAN NOT NULL DEFAULT false,
35
36
  "SessionId" TEXT,
36
37
  "GuestRole" JSONB DEFAULT '{"allowPages": [""], "NotallowPages": [""]}'::jsonb
38
+ "AllowedApps" JSONB DEFAULT '{"allowPages": [""], "NotallowPages": [""]}'::jsonb
37
39
  );
38
40
  ```
39
41
 
package/env.md CHANGED
@@ -2,11 +2,29 @@
2
2
 
3
3
  [<- Back](README.md)
4
4
 
5
+ ## Application Settings
6
+
7
+ ```properties
8
+ APP_NAME=mbkauthe
9
+ ```
10
+
11
+ > **APP_NAME**: Specifies the name of the application. This is used to distinguish one project from another and is critical for ensuring users are restricted to specific apps. It corresponds to the `AllowedApp` column in the Users table.
12
+
5
13
  ## reCAPTCHA Settings
14
+
6
15
  ```properties
7
- RECAPTCHA_SECRET_KEY=123
16
+ RECAPTCHA_ENABLED=true
17
+ RECAPTCHA_SECRET_KEY=your-secret-key
18
+ BYPASS_USERS=["demo", "user1"]
8
19
  ```
9
- > Note: Obtain your secret key from Google reCAPTCHA Admin Console.
20
+
21
+ > **RECAPTCHA_ENABLED**: Set to `true` to enable reCAPTCHA verification.
22
+
23
+ > **RECAPTCHA_SECRET_KEY**: Provide the secret key obtained from the [Google reCAPTCHA Admin Console](https://www.google.com/recaptcha/admin).
24
+
25
+ > **BYPASS_USERS**: Specify an array of usernames (e.g., `["demo", "user1"]`) that will bypass reCAPTCHA verification.
26
+
27
+ > **Note**: Ensure `RECAPTCHA_SECRET_KEY` is set when `RECAPTCHA_ENABLED=true`.
10
28
 
11
29
 
12
30
  ## Session Settings
package/index.js CHANGED
@@ -6,18 +6,29 @@ const mbkautheVar = JSON.parse(process.env.mbkautheVar);
6
6
  if (!mbkautheVar) {
7
7
  throw new Error("mbkautheVar is not defined");
8
8
  }
9
- const requiredKeys = ["RECAPTCHA_SECRET_KEY", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
9
+ const requiredKeys = ["APP_NAME", "RECAPTCHA_Enabled", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
10
10
  requiredKeys.forEach(key => {
11
11
  if (!mbkautheVar[key]) {
12
12
  throw new Error(`mbkautheVar.${key} is required`);
13
13
  }
14
14
  });
15
+ if (mbkautheVar.RECAPTCHA_Enabled === "true") {
16
+ if (mbkautheVar.RECAPTCHA_SECRET_KEY === undefined) {
17
+ throw new Error("mbkautheVar.RECAPTCHA_SECRET_KEY is required");
18
+ }
19
+ }
15
20
  if (mbkautheVar.COOKIE_EXPIRE_TIME !== undefined) {
16
21
  const expireTime = parseFloat(mbkautheVar.COOKIE_EXPIRE_TIME);
17
22
  if (isNaN(expireTime) || expireTime <= 0) {
18
23
  throw new Error("mbkautheVar.COOKIE_EXPIRE_TIME must be a valid positive number");
19
24
  }
20
25
  }
26
+ if (mbkautheVar.BypassUsers !== undefined) {
27
+ if (!Array.isArray(mbkautheVar.BypassUsers)) {
28
+ throw new Error("mbkautheVar.BypassUsers must be a valid array");
29
+ }
30
+ const BypassUsers = mbkautheVar.BypassUsers;
31
+ }
21
32
 
22
33
 
23
34
  export { validateSession, checkRolePermission, validateSessionAndRole, getUserData, authenticate } from "./lib/validateSessionAndRole.js";
package/lib/main.js CHANGED
@@ -8,27 +8,9 @@ import { authenticate } from "./validateSessionAndRole.js";
8
8
  import fetch from 'node-fetch';
9
9
  import cookieParser from "cookie-parser";
10
10
 
11
-
12
-
13
11
  import dotenv from "dotenv";
14
12
  dotenv.config();
15
13
  const mbkautheVar = JSON.parse(process.env.mbkautheVar);
16
- if (!mbkautheVar) {
17
- throw new Error("mbkautheVar is not defined");
18
- }
19
- const requiredKeys = ["RECAPTCHA_SECRET_KEY", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
20
- requiredKeys.forEach(key => {
21
- if (!mbkautheVar[key]) {
22
- throw new Error(`mbkautheVar.${key} is required`);
23
- }
24
- });
25
- if (mbkautheVar.COOKIE_EXPIRE_TIME !== undefined) {
26
- const expireTime = parseFloat(mbkautheVar.COOKIE_EXPIRE_TIME);
27
- if (isNaN(expireTime) || expireTime <= 0) {
28
- throw new Error("mbkautheVar.COOKIE_EXPIRE_TIME must be a valid positive number");
29
- }
30
- }
31
-
32
14
 
33
15
  const router = express.Router();
34
16
  let COOKIE_EXPIRE_TIME = 2 * 24 * 60 * 60 * 1000; // 2 days
@@ -146,26 +128,26 @@ router.post("/mbkauthe/api/login", async (req, res) => {
146
128
  const secretKey = mbkautheVar.RECAPTCHA_SECRET_KEY;
147
129
  const verificationUrl = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${recaptcha}`;
148
130
 
149
- let BypassUsers = ["ibnekhalid", "maaz.waheed", "support"];
150
-
151
- // Bypass recaptcha for specific users
152
- if (!BypassUsers.includes(username)) {
153
- if (!recaptcha) {
154
- console.log("Missing reCAPTCHA token");
155
- return res.status(400).json({ success: false, message: "Please complete the reCAPTCHA" });
156
- }
157
- try {
158
- const response = await fetch(verificationUrl, { method: 'POST' });
159
- const body = await response.json();
160
- console.log("reCAPTCHA verification response:", body); // Log reCAPTCHA response
161
-
162
- if (!body.success) {
163
- console.log("Failed reCAPTCHA verification");
164
- return res.status(400).json({ success: false, message: "Failed reCAPTCHA verification" });
131
+ let BypassUsers = [mbkautheVar.BypassUsers];
132
+ if (mbkautheVar.RECAPTCHA_Enabled === "true") {
133
+ if (!BypassUsers.includes(username)) {
134
+ if (!recaptcha) {
135
+ console.log("Missing reCAPTCHA token");
136
+ return res.status(400).json({ success: false, message: "Please complete the reCAPTCHA" });
137
+ }
138
+ try {
139
+ const response = await fetch(verificationUrl, { method: 'POST' });
140
+ const body = await response.json();
141
+ console.log("reCAPTCHA verification response:", body); // Log reCAPTCHA response
142
+
143
+ if (!body.success) {
144
+ console.log("Failed reCAPTCHA verification");
145
+ return res.status(400).json({ success: false, message: "Failed reCAPTCHA verification" });
146
+ }
147
+ } catch (err) {
148
+ console.log("Error during reCAPTCHA verification:", err);
149
+ return res.status(500).json({ success: false, message: "Internal Server Error" });
165
150
  }
166
- } catch (err) {
167
- console.log("Error during reCAPTCHA verification:", err);
168
- return res.status(500).json({ success: false, message: "Internal Server Error" });
169
151
  }
170
152
  }
171
153
 
@@ -202,6 +184,18 @@ router.post("/mbkauthe/api/login", async (req, res) => {
202
184
  return res.status(403).json({ success: false, message: "Account is inactive" });
203
185
  }
204
186
 
187
+
188
+ if (mbkautheVar.test === "true") {
189
+ // Check if the user is authorized to use the application
190
+ if (result.rows[0].Role !== "SuperAdmin") {
191
+ const allowedApps = result.rows[0].AllowedApps;
192
+ if (!allowedApps || !allowedApps.includes(mbkautheVar.APP_NAME)) {
193
+ console.warn(`User \"${req.session.user.username}\" is not authorized to use the application \"${mbkautheVar.APP_NAME}\"`);
194
+ return res.status(403).json({ success: false, message: `You are not authorized to use the application \"${mbkautheVar.APP_NAME}\"` });
195
+ }
196
+ }
197
+ }
198
+
205
199
  if ((mbkautheVar.MBKAUTH_TWO_FA_ENABLE || "").toLocaleLowerCase() === "true") {
206
200
  let sharedSecret;
207
201
  const query = `SELECT "TwoFAStatus", "TwoFASecret" FROM "TwoFA" WHERE "UserName" = $1`;
package/lib/pool.js CHANGED
@@ -1,25 +1,9 @@
1
1
  import pkg from "pg";
2
2
  const { Pool } = pkg;
3
3
 
4
-
5
4
  import dotenv from "dotenv";
6
5
  dotenv.config();
7
6
  const mbkautheVar = JSON.parse(process.env.mbkautheVar);
8
- if (!mbkautheVar) {
9
- throw new Error("mbkautheVar is not defined");
10
- }
11
- const requiredKeys = ["RECAPTCHA_SECRET_KEY", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
12
- requiredKeys.forEach(key => {
13
- if (!mbkautheVar[key]) {
14
- throw new Error(`mbkautheVar.${key} is required`);
15
- }
16
- });
17
- if (mbkautheVar.COOKIE_EXPIRE_TIME !== undefined) {
18
- const expireTime = parseFloat(mbkautheVar.COOKIE_EXPIRE_TIME);
19
- if (isNaN(expireTime) || expireTime <= 0) {
20
- throw new Error("mbkautheVar.COOKIE_EXPIRE_TIME must be a valid positive number");
21
- }
22
- }
23
7
 
24
8
  // PostgreSQL connection pool for pool
25
9
  const poolConfig = {
@@ -1,4 +1,5 @@
1
1
  import { dblogin } from "./pool.js";
2
+ const mbkautheVar = JSON.parse(process.env.mbkautheVar);
2
3
 
3
4
  async function validateSession(req, res, next) {
4
5
  // First check if we have a session cookie
@@ -53,6 +54,23 @@ async function validateSession(req, res, next) {
53
54
  });
54
55
  }
55
56
 
57
+ if (mbkautheVar.test === "true") {
58
+ if (result.rows[0].Role !== "SuperAdmin") {
59
+ const allowedApps = result.rows[0].AllowedApps;
60
+ if (!allowedApps || !allowedApps.includes(mbkautheVar.APP_NAME)) {
61
+ console.warn(
62
+ `User \"${req.session.user.username}\" is not authorized to use the application \"${mbkautheVar.APP_NAME}\"`
63
+ );
64
+ req.session.destroy();
65
+ res.clearCookie("connect.sid");
66
+ return res.render("templates/Error/AccountInactive.handlebars", {
67
+ currentUrl: req.originalUrl,
68
+ });
69
+ }
70
+ }
71
+ }
72
+
73
+
56
74
  next();
57
75
  } catch (err) {
58
76
  console.error("Session validation error:", err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mbkauthe",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "MBKTechStudio's reusable authentication system for Node.js applications.",
5
5
  "main": "index.js",
6
6
  "type": "module",