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 +50 -86
- package/lib/validateSessionAndRole.js +31 -15
- package/package.json +1 -1
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;
|
|
39
|
+
COOKIE_EXPIRE_TIME = parsedExpireTime * 24 * 60 * 60 * 1000;
|
|
40
40
|
} else {
|
|
41
|
-
console.warn("Invalid COOKIE_EXPIRE_TIME
|
|
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
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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.
|
|
86
|
+
if (!req.session.user && req.cookies.sessionId) {
|
|
96
87
|
try {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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 (
|
|
114
|
-
console.
|
|
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
|
-
|
|
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("
|
|
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();
|
|
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
|
|
182
|
+
export { validateSession, checkRolePermission, validateSessionAndRole, getUserData, authenticate };
|