mbkauthe 1.0.6 → 1.0.7

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/lib/main.js CHANGED
@@ -31,111 +31,75 @@ if (mbkautheVar.COOKIE_EXPIRE_TIME !== undefined) {
31
31
 
32
32
 
33
33
  const router = express.Router();
34
- let COOKIE_EXPIRE_TIME = 2 * 24 * 60 * 60 * 1000; //2 days
34
+ let COOKIE_EXPIRE_TIME = 2 * 24 * 60 * 60 * 1000; // 2 days
35
35
 
36
36
  try {
37
37
  const parsedExpireTime = parseInt(mbkautheVar.COOKIE_EXPIRE_TIME, 10);
38
38
  if (!isNaN(parsedExpireTime) && parsedExpireTime > 0) {
39
- COOKIE_EXPIRE_TIME = parsedExpireTime * 24 * 60 * 60 * 1000; // Convert days to milliseconds
39
+ COOKIE_EXPIRE_TIME = parsedExpireTime * 24 * 60 * 60 * 1000;
40
40
  } else {
41
- console.warn("Invalid COOKIE_EXPIRE_TIME in environment variables, using default value");
41
+ console.warn("Invalid COOKIE_EXPIRE_TIME, using default value");
42
42
  }
43
- console.log(`Cookie expiration time set to ${COOKIE_EXPIRE_TIME / (24 * 60 * 60 * 1000)} days for deployed environment`);
44
43
  } catch (error) {
45
44
  console.log("Error parsing COOKIE_EXPIRE_TIME:", error);
46
45
  }
47
46
 
48
- router.use(express.json());
49
- router.use(express.urlencoded({ extended: true }));
50
-
51
- router.use(
52
- session({
53
- store: new PgSession({
54
- pool: dblogin, // Connection pool
55
- tableName: "session", // Use another table-name than the default "session" one
56
- }),
57
- secret: mbkautheVar.SESSION_SECRET_KEY, // Replace with your secret key
58
- resave: false,
59
- saveUninitialized: false,
60
- cookie: {
61
- maxAge: COOKIE_EXPIRE_TIME,
62
- DOMAIN: mbkautheVar.IS_DEPLOYED === 'true' ? `.${mbkautheVar.DOMAIN}` : undefined, // Use root DOMAIN for subDOMAIN sharing
63
- httpOnly: true,
64
- secure: mbkautheVar.IS_DEPLOYED === 'true', // Use secure cookies in production
65
- },
66
- })
67
- );
68
-
69
-
70
-
71
- router.use(cookieParser()); // Use cookie-parser middleware
72
-
47
+ // Enable CORS for subdomains
73
48
  router.use((req, res, next) => {
74
- if (req.session && req.session.user) {
75
- const userAgent = req.headers["user-agent"];
76
- const userIp =
77
- req.headers["x-forwarded-for"] || req.connection.remoteAddress;
78
- const formattedIp = userIp === "::1" ? "127.0.0.1" : userIp;
79
-
80
- req.session.otherInfo = {
81
- ip: formattedIp,
82
- browser: userAgent,
83
- };
84
-
85
- next();
86
- } else {
87
- next();
49
+ const origin = req.headers.origin;
50
+ if (origin && origin.endsWith(`.${mbkautheVar.DOMAIN}`)) {
51
+ res.header('Access-Control-Allow-Origin', origin);
52
+ res.header('Access-Control-Allow-Credentials', 'true');
53
+ res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
54
+ res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
88
55
  }
56
+ next();
89
57
  });
90
58
 
91
- // Save the username in a cookie, the cookie user name is use
92
- // for displaying user name in profile menu. This cookie is not use anyelse where.
93
- // So it is safe to use.
59
+ router.use(express.json());
60
+ router.use(express.urlencoded({ extended: true }));
61
+ router.use(cookieParser());
62
+
63
+ // Configure session with proper domain settings
64
+ const sessionConfig = {
65
+ store: new PgSession({
66
+ pool: dblogin,
67
+ tableName: "session",
68
+ }),
69
+ secret: mbkautheVar.SESSION_SECRET_KEY,
70
+ resave: false,
71
+ saveUninitialized: false,
72
+ cookie: {
73
+ maxAge: COOKIE_EXPIRE_TIME,
74
+ domain: mbkautheVar.IS_DEPLOYED === 'true' ? `.${mbkautheVar.DOMAIN}` : undefined,
75
+ httpOnly: true,
76
+ secure: mbkautheVar.IS_DEPLOYED === 'true',
77
+ sameSite: 'lax',
78
+ },
79
+ name: 'mbkauthe.sid' // Unique session cookie name
80
+ };
81
+
82
+ router.use(session(sessionConfig));
83
+
84
+ // Middleware to handle session restoration from sessionId cookie
94
85
  router.use(async (req, res, next) => {
95
- if (req.session && req.session.user) {
86
+ if (!req.session.user && req.cookies.sessionId) {
96
87
  try {
97
-
98
- res.cookie("username", req.session.user.username, {
99
- maxAge: COOKIE_EXPIRE_TIME,
100
- });
101
-
102
- const query = `SELECT "Role" FROM "Users" WHERE "UserName" = $1`;
103
- const result = await dblogin.query(query, [req.session.user.username]);
88
+ const sessionId = req.cookies.sessionId;
89
+ const query = `SELECT * FROM "Users" WHERE "SessionId" = $1`;
90
+ const result = await dblogin.query(query, [sessionId]);
104
91
 
105
92
  if (result.rows.length > 0) {
106
- req.session.user.role = result.rows[0].Role;
107
- res.cookie("userRole", req.session.user.role, {
108
- maxAge: COOKIE_EXPIRE_TIME,
109
- });
110
- } else {
111
- req.session.user.role = null;
93
+ const user = result.rows[0];
94
+ req.session.user = {
95
+ id: user.id,
96
+ username: user.UserName,
97
+ sessionId,
98
+ };
99
+ console.log(`Session restored for user: ${user.UserName}`);
112
100
  }
113
- } catch (error) {
114
- console.log("Error fetching user role:", error.message);
115
- req.session.user.role = null; // Fallback to null role
116
- }
117
- }
118
- next();
119
- });
120
-
121
- router.use(async (req, res, next) => {
122
- // Check for sessionId cookie if session is not initialized
123
- if (!req.session.user && req.cookies && req.cookies.sessionId) {
124
- console.log("Restoring session from sessionId cookie"); // Log session restoration
125
- const sessionId = req.cookies.sessionId;
126
- const query = `SELECT * FROM "Users" WHERE "SessionId" = $1`;
127
- const result = await dblogin.query(query, [sessionId]);
128
-
129
- if (result.rows.length > 0) {
130
- const user = result.rows[0];
131
- req.session.user = {
132
- id: user.id,
133
- username: user.UserName,
134
- sessionId,
135
- };
136
- console.log(`Session restored for user: ${user.UserName}`); // Log successful session restoration
137
- } else {
138
- console.warn("No matching session found for sessionId"); // Log if no session is found
101
+ } catch (err) {
102
+ console.error("Session restoration error:", err);
139
103
  }
140
104
  }
141
105
  next();
@@ -1,6 +1,27 @@
1
1
  import { dblogin } from "./pool.js";
2
2
 
3
3
  async function validateSession(req, res, next) {
4
+ // First check if we have a session cookie
5
+ if (!req.session.user && req.cookies.sessionId) {
6
+ try {
7
+ const sessionId = req.cookies.sessionId;
8
+ const query = `SELECT * FROM "Users" WHERE "SessionId" = $1`;
9
+ const result = await dblogin.query(query, [sessionId]);
10
+
11
+ if (result.rows.length > 0) {
12
+ const user = result.rows[0];
13
+ req.session.user = {
14
+ id: user.id,
15
+ username: user.UserName,
16
+ sessionId,
17
+ };
18
+ }
19
+ } catch (err) {
20
+ console.error("Session validation error:", err);
21
+ return res.status(500).json({ success: false, message: "Internal Server Error" });
22
+ }
23
+ }
24
+
4
25
  if (!req.session.user) {
5
26
  return res.render("templates/Error/NotLoggedIn.handlebars", {
6
27
  currentUrl: req.originalUrl,
@@ -12,37 +33,32 @@ async function validateSession(req, res, next) {
12
33
  const query = `SELECT "SessionId", "Active" FROM "Users" WHERE "id" = $1`;
13
34
  const result = await dblogin.query(query, [id]);
14
35
 
15
- // Check if user exists and session ID matches
16
36
  if (result.rows.length === 0 || result.rows[0].SessionId !== sessionId) {
17
- console.log(
18
- `Session invalidated for user \"${req.session.user.username}\"`
19
- );
37
+ console.log(`Session invalidated for user "${req.session.user.username}"`);
20
38
  req.session.destroy();
21
- // ...existing code...
39
+ res.clearCookie("mbkauthe.sid", { domain: `.${mbkautheVar.DOMAIN}` });
40
+ res.clearCookie("sessionId", { domain: `.${mbkautheVar.DOMAIN}` });
22
41
  return res.render("templates/Error/SessionExpire.handlebars", {
23
42
  currentUrl: req.originalUrl,
24
43
  });
25
- // ...existing code...
26
44
  }
27
45
 
28
- // Check if the user account is inactive
29
46
  if (!result.rows[0].Active) {
30
- console.log(
31
- `Account is inactive for user \"${req.session.user.username}\"`
32
- );
47
+ console.log(`Account is inactive for user "${req.session.user.username}"`);
33
48
  req.session.destroy();
34
- res.clearCookie("connect.sid");
49
+ res.clearCookie("mbkauthe.sid", { domain: `.${mbkautheVar.DOMAIN}` });
50
+ res.clearCookie("sessionId", { domain: `.${mbkautheVar.DOMAIN}` });
35
51
  return res.render("templates/Error/AccountInactive.handlebars", {
36
52
  currentUrl: req.originalUrl,
37
53
  });
38
54
  }
39
55
 
40
- next(); // Proceed if everything is valid
56
+ next();
41
57
  } catch (err) {
42
58
  console.error("Session validation error:", err);
43
59
  res.status(500).json({ success: false, message: "Internal Server Error" });
44
60
  }
45
- }
61
+ }
46
62
 
47
63
  const checkRolePermission = (requiredRole) => {
48
64
  return async (req, res, next) => {
@@ -86,7 +102,7 @@ const checkRolePermission = (requiredRole) => {
86
102
  .json({ success: false, message: "Internal Server Error" });
87
103
  }
88
104
  };
89
- };
105
+ };
90
106
 
91
107
  const validateSessionAndRole = (requiredRole) => {
92
108
  return async (req, res, next) => {
@@ -163,4 +179,4 @@ const authenticate = (authentication) => {
163
179
  };
164
180
  };
165
181
 
166
- export { validateSession, checkRolePermission, validateSessionAndRole, getUserData , authenticate};
182
+ export { validateSession, checkRolePermission, validateSessionAndRole, getUserData, authenticate };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mbkauthe",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "MBKTechStudio's reusable authentication system for Node.js applications.",
5
5
  "main": "index.js",
6
6
  "type": "module",