mbkauthe 1.0.5 → 1.0.6

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 ADDED
@@ -0,0 +1,11 @@
1
+ mbkautheVar='{
2
+ "RECAPTCHA_SECRET_KEY": "your-recaptcha-secret-key",
3
+ "SESSION_SECRET_KEY": "your-session-secret-key",
4
+ "IS_DEPLOYED": "true",
5
+ "LOGIN_DB": "postgres://username:password@host:port/database",
6
+ "MBKAUTH_TWO_FA_ENABLE": "false",
7
+ "COOKIE_EXPIRE_TIME": 2,
8
+ "DOMAIN": "yourdomain.com"
9
+ }'
10
+
11
+ # See env.md for more details
@@ -4,9 +4,16 @@ on:
4
4
  branches:
5
5
  - main
6
6
 
7
+ permissions:
8
+ contents: read
9
+ packages: write
10
+
7
11
  jobs:
8
12
  publish:
9
13
  runs-on: ubuntu-latest
14
+ permissions:
15
+ contents: read
16
+ packages: write
10
17
  steps:
11
18
  - name: Checkout code
12
19
  uses: actions/checkout@v3
package/README.md CHANGED
@@ -55,13 +55,15 @@ app.listen(3000, () => {
55
55
 
56
56
  Example `.env` file:
57
57
  ```code
58
- RECAPTCHA_SECRET_KEY=your-recaptcha-secret-key
59
- SESSION_SECRET_KEY=your-session-secret-key
60
- LOGIN_DB=postgres://username:password@host:port/database
61
- DOMAIN=yourdomain.com
62
- IS_DEPLOYED=true
63
- MBKAUTH_TWO_FA_ENABLE=false
64
- COOKIE_EXPIRE_TIME=2
58
+ mbkautheVar='{
59
+ "RECAPTCHA_SECRET_KEY": "your-recaptcha-secret-key",
60
+ "SESSION_SECRET_KEY": "your-session-secret-key",
61
+ "IS_DEPLOYED": "true",
62
+ "LOGIN_DB": "postgres://username:password@host:port/database",
63
+ "MBKAUTH_TWO_FA_ENABLE": "false",
64
+ "COOKIE_EXPIRE_TIME": 2,
65
+ "DOMAIN": "yourdomain.com"
66
+ }'
65
67
  ```
66
68
 
67
69
  ## API Endpoints
package/index.js CHANGED
@@ -1,23 +1,25 @@
1
- import dotenv from "dotenv";
2
- import Joi from "joi";
3
1
  import router from "./lib/main.js";
2
+
3
+ import dotenv from "dotenv";
4
4
  dotenv.config();
5
+ const mbkautheVar = JSON.parse(process.env.mbkautheVar);
6
+ if (!mbkautheVar) {
7
+ throw new Error("mbkautheVar is not defined");
8
+ }
9
+ const requiredKeys = ["RECAPTCHA_SECRET_KEY", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
10
+ requiredKeys.forEach(key => {
11
+ if (!mbkautheVar[key]) {
12
+ throw new Error(`mbkautheVar.${key} is required`);
13
+ }
14
+ });
15
+ if (mbkautheVar.COOKIE_EXPIRE_TIME !== undefined) {
16
+ const expireTime = parseFloat(mbkautheVar.COOKIE_EXPIRE_TIME);
17
+ if (isNaN(expireTime) || expireTime <= 0) {
18
+ throw new Error("mbkautheVar.COOKIE_EXPIRE_TIME must be a valid positive number");
19
+ }
20
+ }
5
21
 
6
- const envSchema = Joi.object({
7
- RECAPTCHA_SECRET_KEY: Joi.string().required(),
8
- SESSION_SECRET_KEY: Joi.string().required(),
9
- IS_DEPLOYED: Joi.string().valid("true", "false").required(),
10
- LOGIN_DB: Joi.string().uri().required(),
11
- MBKAUTH_TWO_FA_ENABLE: Joi.string().valid("true", "false").required(),
12
- COOKIE_EXPIRE_TIME: Joi.number().integer().positive(),
13
- DOMAIN: Joi.string().required(),
14
- }).unknown(true);
15
22
 
16
- const { error } = envSchema.validate(process.env);
17
- if (error) {
18
- throw new Error(`Environment variable validation error: ${error.message}`);
19
- }
20
- export { validateSession, checkRolePermission, validateSessionAndRole, getUserData } from "./lib/validateSessionAndRole.js";
21
- export { authenticate } from "./lib/auth.js";
23
+ export { validateSession, checkRolePermission, validateSessionAndRole, getUserData, authenticate } from "./lib/validateSessionAndRole.js";
22
24
  export { dblogin } from "./lib/pool.js";
23
25
  export default router;
package/lib/main.js CHANGED
@@ -3,24 +3,44 @@ import crypto from "crypto";
3
3
  import session from "express-session";
4
4
  import pgSession from "connect-pg-simple";
5
5
  const PgSession = pgSession(session);
6
- import dotenv from "dotenv";
7
6
  import { dblogin } from "./pool.js";
8
- import { authenticate } from "./auth.js";
7
+ import { authenticate } from "./validateSessionAndRole.js";
9
8
  import fetch from 'node-fetch';
10
- import cookieParser from "cookie-parser"; // Import cookie-parser
9
+ import cookieParser from "cookie-parser";
10
+
11
11
 
12
+
13
+ import dotenv from "dotenv";
12
14
  dotenv.config();
15
+ 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
+
13
33
  const router = express.Router();
14
34
  let COOKIE_EXPIRE_TIME = 2 * 24 * 60 * 60 * 1000; //2 days
15
35
 
16
36
  try {
17
- const parsedExpireTime = parseInt(process.env.COOKIE_EXPIRE_TIME, 10);
37
+ const parsedExpireTime = parseInt(mbkautheVar.COOKIE_EXPIRE_TIME, 10);
18
38
  if (!isNaN(parsedExpireTime) && parsedExpireTime > 0) {
19
39
  COOKIE_EXPIRE_TIME = parsedExpireTime * 24 * 60 * 60 * 1000; // Convert days to milliseconds
20
40
  } else {
21
41
  console.warn("Invalid COOKIE_EXPIRE_TIME in environment variables, using default value");
22
42
  }
23
- console.log(`Cookie expiration time set to ${COOKIE_EXPIRE_TIME} days for deployed environment`);
43
+ console.log(`Cookie expiration time set to ${COOKIE_EXPIRE_TIME / (24 * 60 * 60 * 1000)} days for deployed environment`);
24
44
  } catch (error) {
25
45
  console.log("Error parsing COOKIE_EXPIRE_TIME:", error);
26
46
  }
@@ -34,14 +54,14 @@ router.use(
34
54
  pool: dblogin, // Connection pool
35
55
  tableName: "session", // Use another table-name than the default "session" one
36
56
  }),
37
- secret: process.env.SESSION_SECRET_KEY, // Replace with your secret key
57
+ secret: mbkautheVar.SESSION_SECRET_KEY, // Replace with your secret key
38
58
  resave: false,
39
59
  saveUninitialized: false,
40
60
  cookie: {
41
61
  maxAge: COOKIE_EXPIRE_TIME,
42
- DOMAIN: process.env.IS_DEPLOYED === 'true' ? `.${process.env.DOMAIN}` : undefined, // Use root DOMAIN for subDOMAIN sharing
62
+ DOMAIN: mbkautheVar.IS_DEPLOYED === 'true' ? `.${mbkautheVar.DOMAIN}` : undefined, // Use root DOMAIN for subDOMAIN sharing
43
63
  httpOnly: true,
44
- secure: process.env.IS_DEPLOYED === 'true', // Use secure cookies in production
64
+ secure: mbkautheVar.IS_DEPLOYED === 'true', // Use secure cookies in production
45
65
  },
46
66
  })
47
67
  );
@@ -123,7 +143,7 @@ router.use(async (req, res, next) => {
123
143
 
124
144
  //Invoke-RestMethod -Uri http://localhost:3030/terminateAllSessions -Method POST
125
145
  // Terminate all sessions route
126
- router.post("/mbkauthe/api/terminateAllSessions", authenticate(process.env.Main_SECRET_TOKEN), async (req, res) => {
146
+ router.post("/mbkauthe/api/terminateAllSessions", authenticate(mbkautheVar.Main_SECRET_TOKEN), async (req, res) => {
127
147
  try {
128
148
  await dblogin.query(`UPDATE "Users" SET "SessionId" = NULL`);
129
149
 
@@ -159,11 +179,17 @@ router.post("/mbkauthe/api/login", async (req, res) => {
159
179
  const { username, password, token, recaptcha } = req.body;
160
180
  console.log(`Login attempt for username: ${username}`); // Log username
161
181
 
162
- const secretKey = process.env.RECAPTCHA_SECRET_KEY;
182
+ const secretKey = mbkautheVar.RECAPTCHA_SECRET_KEY;
163
183
  const verificationUrl = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${recaptcha}`;
164
184
 
185
+ let BypassUsers = ["ibnekhalid", "maaz.waheed", "support"];
186
+
165
187
  // Bypass recaptcha for specific users
166
- if (username !== "ibnekhalid" && username !== "maaz.waheed" && username !== "support") {
188
+ if (!BypassUsers.includes(username)) {
189
+ if (!recaptcha) {
190
+ console.log("Missing reCAPTCHA token");
191
+ return res.status(400).json({ success: false, message: "Please complete the reCAPTCHA" });
192
+ }
167
193
  try {
168
194
  const response = await fetch(verificationUrl, { method: 'POST' });
169
195
  const body = await response.json();
@@ -187,14 +213,6 @@ router.post("/mbkauthe/api/login", async (req, res) => {
187
213
  });
188
214
  }
189
215
 
190
- console.log("RECAPTCHA_SECRET_KEY:", process.env.RECAPTCHA_SECRET_KEY); // Log reCAPTCHA secret key
191
- console.log("SESSION_SECRET_KEY:", process.env.SESSION_SECRET_KEY); // Log reCAPTCHA secret key
192
- console.log("LOGIN_DB:", process.env.LOGIN_DB); // Log reCAPTCHA secret key
193
- console.log("COOKIE_EXPIRE_TIME:", process.env.COOKIE_EXPIRE_TIME); // Log reCAPTCHA secret key
194
- console.log("DOMAIN:", process.env.DOMAIN); // Log reCAPTCHA secret key
195
- console.log("IS_DEPLOYED:", process.env.IS_DEPLOYED); // Log reCAPTCHA secret key
196
- console.log("MBKAUTH_TWO_FA_ENABLE:", process.env.MBKAUTH_TWO_FA_ENABLE); // Log reCAPTCHA secret key
197
-
198
216
  try {
199
217
  // Query to check if the username exists
200
218
  const userQuery = `SELECT * FROM "Users" WHERE "UserName" = $1`;
@@ -220,7 +238,7 @@ router.post("/mbkauthe/api/login", async (req, res) => {
220
238
  return res.status(403).json({ success: false, message: "Account is inactive" });
221
239
  }
222
240
 
223
- if ((process.env.MBKAUTH_TWO_FA_ENABLE || "").toLocaleLowerCase() === "true") {
241
+ if ((mbkautheVar.MBKAUTH_TWO_FA_ENABLE || "").toLocaleLowerCase() === "true") {
224
242
  let sharedSecret;
225
243
  const query = `SELECT "TwoFAStatus", "TwoFASecret" FROM "TwoFA" WHERE "UserName" = $1`;
226
244
  const twoFAResult = await dblogin.query(query, [username]);
@@ -267,9 +285,9 @@ router.post("/mbkauthe/api/login", async (req, res) => {
267
285
  // Set a cookie accessible across subDOMAINs
268
286
  res.cookie("sessionId", sessionId, {
269
287
  maxAge: COOKIE_EXPIRE_TIME,
270
- DOMAIN: process.env.IS_DEPLOYED === 'true' ? `.${process.env.DOMAIN}` : undefined, // Use DOMAIN only in production
288
+ DOMAIN: mbkautheVar.IS_DEPLOYED === 'true' ? `.${mbkautheVar.DOMAIN}` : undefined, // Use DOMAIN only in production
271
289
  httpOnly: true,
272
- secure: process.env.IS_DEPLOYED === 'true', // Use secure cookies in production
290
+ secure: mbkautheVar.IS_DEPLOYED === 'true', // Use secure cookies in production
273
291
  });
274
292
  console.log(`Cookie set for user: ${user.UserName}, sessionId: ${sessionId}`); // Log cookie setting
275
293
 
package/lib/pool.js CHANGED
@@ -1,12 +1,29 @@
1
1
  import pkg from "pg";
2
2
  const { Pool } = pkg;
3
- import dotenv from "dotenv";
4
3
 
4
+
5
+ import dotenv from "dotenv";
5
6
  dotenv.config();
7
+ 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
+ }
6
23
 
7
24
  // PostgreSQL connection pool for pool
8
25
  const poolConfig = {
9
- connectionString: process.env.LOGIN_DB,
26
+ connectionString: mbkautheVar.LOGIN_DB,
10
27
  ssl: {
11
28
  rejectUnauthorized: true,
12
29
  },
@@ -149,4 +149,18 @@ async function getUserData(UserName, parameters) {
149
149
  }
150
150
  }
151
151
 
152
- export { validateSession, checkRolePermission, validateSessionAndRole, getUserData };
152
+ const authenticate = (authentication) => {
153
+ return (req, res, next) => {
154
+ const token = req.headers["authorization"];
155
+ console.log(`Received token: ${token}`);
156
+ if (token === authentication) {
157
+ console.log("Authentication successful");
158
+ next();
159
+ } else {
160
+ console.log("Authentication failed");
161
+ res.status(401).send("Unauthorized");
162
+ }
163
+ };
164
+ };
165
+
166
+ export { validateSession, checkRolePermission, validateSessionAndRole, getUserData , authenticate};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mbkauthe",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "MBKTechStudio's reusable authentication system for Node.js applications.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -31,7 +31,6 @@
31
31
  "dotenv": "^16.4.7",
32
32
  "express": "^5.1.0",
33
33
  "express-session": "^1.18.1",
34
- "joi": "^17.13.3",
35
34
  "node-fetch": "^3.3.2",
36
35
  "pg": "^8.14.1"
37
36
  }
package/lib/auth.js DELETED
@@ -1,13 +0,0 @@
1
- export const authenticate = (authentication) => {
2
- return (req, res, next) => {
3
- const token = req.headers["authorization"];
4
- console.log(`Received token: ${token}`);
5
- if (token === authentication) {
6
- console.log("Authentication successful");
7
- next();
8
- } else {
9
- console.log("Authentication failed");
10
- res.status(401).send("Unauthorized");
11
- }
12
- };
13
- };