mbkauthe 1.1.6 → 1.1.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/index.js +20 -2
- package/lib/info.js +8 -0
- package/package.json +5 -2
- package/views/loginmbkauthe.handlebars +257 -0
package/index.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import express from "express"; // Add this line
|
|
2
2
|
import router from "./lib/main.js";
|
|
3
|
-
|
|
3
|
+
import { engine } from "express-handlebars";
|
|
4
4
|
import dotenv from "dotenv";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
|
|
5
8
|
dotenv.config();
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
6
12
|
let mbkautheVar;
|
|
13
|
+
|
|
7
14
|
try {
|
|
8
15
|
mbkautheVar = JSON.parse(process.env.mbkautheVar);
|
|
9
16
|
} catch (error) {
|
|
@@ -35,9 +42,9 @@ if (mbkautheVar.BypassUsers !== undefined) {
|
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
44
|
|
|
45
|
+
const app = express();
|
|
38
46
|
if (process.env.test === "true") {
|
|
39
47
|
console.log("Test mode is enabled. Starting server in test mode.");
|
|
40
|
-
const app = express();
|
|
41
48
|
const port = 3000;
|
|
42
49
|
app.use(router);
|
|
43
50
|
app.listen(port, () => {
|
|
@@ -45,6 +52,17 @@ if (process.env.test === "true") {
|
|
|
45
52
|
});
|
|
46
53
|
}
|
|
47
54
|
|
|
55
|
+
app.set("views", path.join(__dirname, "node_modules/mbkauthe/views"));
|
|
56
|
+
|
|
57
|
+
app.engine("handlebars", engine({
|
|
58
|
+
defaultLayout: false,
|
|
59
|
+
partialsDir: [
|
|
60
|
+
path.join(__dirname, "node_modules/mbkauthe/views"),
|
|
61
|
+
],
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
app.set("view engine", "handlebars");
|
|
65
|
+
|
|
48
66
|
export { validateSession, checkRolePermission, validateSessionAndRole, getUserData, authenticate, authapi } from "./lib/validateSessionAndRole.js";
|
|
49
67
|
export { dblogin } from "./lib/pool.js";
|
|
50
68
|
export default router;
|
package/lib/info.js
CHANGED
|
@@ -15,6 +15,14 @@ const mbkautheVar = JSON.parse(process.env.mbkautheVar);
|
|
|
15
15
|
|
|
16
16
|
const router = express.Router();
|
|
17
17
|
|
|
18
|
+
router.get(["/mbkauthe/login"], (req, res) => {
|
|
19
|
+
return res.render("loginmbkauthe", {
|
|
20
|
+
layout: false,
|
|
21
|
+
userLoggedIn: !!req.session?.user,
|
|
22
|
+
UserName: req.session?.user?.username || ''
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
18
26
|
async function getLatestVersion() {
|
|
19
27
|
try {
|
|
20
28
|
const response = await fetch('https://raw.githubusercontent.com/MIbnEKhalid/mbkauthe/main/package.json');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mbkauthe",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "MBKTechStudio's reusable authentication system for Node.js applications.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,11 +32,14 @@
|
|
|
32
32
|
"cookie-parser": "^1.4.7",
|
|
33
33
|
"dotenv": "^16.4.7",
|
|
34
34
|
"express": "^5.1.0",
|
|
35
|
+
"express-handlebars": "^8.0.1",
|
|
35
36
|
"express-rate-limit": "^7.5.0",
|
|
36
37
|
"express-session": "^1.18.1",
|
|
37
38
|
"marked": "^15.0.11",
|
|
38
39
|
"node-fetch": "^3.3.2",
|
|
39
|
-
"
|
|
40
|
+
"path": "^0.12.7",
|
|
41
|
+
"pg": "^8.14.1",
|
|
42
|
+
"url": "^0.11.4"
|
|
40
43
|
},
|
|
41
44
|
"devDependencies": {
|
|
42
45
|
"nodemon": "^2.0.22"
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" dir="ltr">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<title>Login</title>
|
|
6
|
+
<script src="/Assets/Scripts/logout.js"></script>
|
|
7
|
+
<meta name="description"
|
|
8
|
+
content="Log in to portal.mbktechstudio.com to access your resources and manage projects securely.">
|
|
9
|
+
<meta name="keywords" content="MBK Tech Studio, Web-Portal, Web, Portal, Admin-Panel, Admin, login">
|
|
10
|
+
<meta property="og:title" content="Portal Login | MBK Tech STudio" />
|
|
11
|
+
<meta property="og:image" content="https://www.mbktechstudio.com/Assets/Images/Icon/logo.png" />
|
|
12
|
+
<meta property="og:url" content="https://portal.mbktechstudio.com/login">
|
|
13
|
+
<script type="application/ld+json">
|
|
14
|
+
{ "@context": "https://schema.org", "@type": "Organization", "name": "MBK Tech Studio", "url":
|
|
15
|
+
"https://portal.mbktechstudio.com/login", "logo": "https://www.mbktechstudio.com/Assets/Images/Icon/logo.png", "description":
|
|
16
|
+
"MBK Tech Studio: Log in to portal.mbktechstudio.com to access your resources and manage projects securely." }
|
|
17
|
+
</script>
|
|
18
|
+
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
|
19
|
+
<style>
|
|
20
|
+
.info {
|
|
21
|
+
font-family: 'Open Sans', sans-serif;
|
|
22
|
+
font-size: 14px;
|
|
23
|
+
color: #0c5460;
|
|
24
|
+
background-color: #d1ecf1;
|
|
25
|
+
border: 1px solid #ddd;
|
|
26
|
+
border-radius: 8px;
|
|
27
|
+
padding: 5px 15px;
|
|
28
|
+
margin-top: 5px;
|
|
29
|
+
font-weight: 500;
|
|
30
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
31
|
+
line-height: 1.2;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.info span {
|
|
35
|
+
color: #007bff;
|
|
36
|
+
/* Highlight for the info icon */
|
|
37
|
+
margin-right: 8px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
section .button {
|
|
41
|
+
margin: 0 0 2px !important;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
section .button button {
|
|
45
|
+
margin: 0 !important;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.back {
|
|
49
|
+
top: 0;
|
|
50
|
+
color: #fff;
|
|
51
|
+
position: absolute;
|
|
52
|
+
margin-top: 10px;
|
|
53
|
+
font-size: 20px;
|
|
54
|
+
transition: color 0.3s ease;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.back:hover {
|
|
58
|
+
color: rgb(185, 185, 185);
|
|
59
|
+
transition: color 0.3s ease;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@media(max-width: 1200px) {
|
|
63
|
+
.user-box label {
|
|
64
|
+
left: 2% !important;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@media(max-width: 1200px) {
|
|
69
|
+
.user-box label {
|
|
70
|
+
left: 2% !important;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.recaptcha-container {
|
|
75
|
+
display: flex;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
align-items: center;
|
|
78
|
+
margin-top: 7px;
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
81
|
+
</head>
|
|
82
|
+
{{> header1 }}
|
|
83
|
+
|
|
84
|
+
<body>
|
|
85
|
+
<section class="about" id="about">
|
|
86
|
+
<div class="content">
|
|
87
|
+
<div class="portalbox">
|
|
88
|
+
<div class="title">
|
|
89
|
+
<span style="font-size:30px;">Login</span>
|
|
90
|
+
</div>
|
|
91
|
+
<form id="loginForm" action="/login" method="POST">
|
|
92
|
+
<div class="back" onclick="loadpage('/')">
|
|
93
|
+
<i class="fa-solid fa-arrow-left"></i>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="user-box">
|
|
96
|
+
<input id="loginUsername" type="text" name="username" required pattern="^[a-z0-9.]+$"
|
|
97
|
+
title="Username must contain lowercase letters, numbers, and periods only, no spaces, no special characters."
|
|
98
|
+
oninput="this.value = this.value.toLowerCase().replace(/[^a-z0-9.]/g, '')" />
|
|
99
|
+
<label>User Name</label>
|
|
100
|
+
<span class="info-icon" onclick="usernameinfo()">
|
|
101
|
+
<i class="fa fa-info-circle"></i>
|
|
102
|
+
</span>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="user-box">
|
|
105
|
+
<input id="loginPassword" type="password" name="Password" required="" />
|
|
106
|
+
<label>Password</label>
|
|
107
|
+
<span class="password-toggle-icon">
|
|
108
|
+
<i class="fa fa-eye"></i>
|
|
109
|
+
</span>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="user-box" id="tokenCon" style="display: none;">
|
|
112
|
+
<input id="token" type="text" class="no-spinner" name="token" pattern="\d{6}"
|
|
113
|
+
title="Token must be exactly 6 digits" maxlength="6" minlength="6" />
|
|
114
|
+
<label>Token</label>
|
|
115
|
+
<span class="info-icon" onclick="tokeninfo()">
|
|
116
|
+
<i class="fa fa-info-circle"></i>
|
|
117
|
+
</span>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="wrap">
|
|
120
|
+
<div class="button">
|
|
121
|
+
<button style="font-size: 17px;" type="submit">Login</button>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</form>
|
|
125
|
+
{{#if userLoggedIn }}
|
|
126
|
+
{{> alreadyloggedin UserName=UserName }}
|
|
127
|
+
{{/if }}
|
|
128
|
+
<p class="info maincssp">
|
|
129
|
+
<span class="">
|
|
130
|
+
<i class="fa fa-info-circle"></i>
|
|
131
|
+
</span>By Logging In, You Are Automatically Agreeing To Our
|
|
132
|
+
<a class="links" href="/info/Terms&Conditions">Use Of Terms & Conditions
|
|
133
|
+
</a>
|
|
134
|
+
</p>
|
|
135
|
+
<div class="recaptcha-container">
|
|
136
|
+
<div class="g-recaptcha" data-theme="dark" data-sitekey="6LfhaPgqAAAAAPgOw7r3rNOHKKfh5d7K3MMJeUHo">
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</section>
|
|
142
|
+
</body>
|
|
143
|
+
{{> footer }}
|
|
144
|
+
<script>
|
|
145
|
+
function usernameinfo() {
|
|
146
|
+
showMessage(
|
|
147
|
+
'<div style="">If you are a member of the Mbk Tech Studio team, your username is the first part of your email address (e.' +
|
|
148
|
+
'g., for abc.xyz@mbktechstudio.com, your username is abc.xyz). If you are a guest or have forgotten your username and pas' +
|
|
149
|
+
'sword, please fill contact form at <a class="links" href="https://www.mbktechstudio.com/Support">mbktechstudio.com/Suppo' +
|
|
150
|
+
'rt</a> or contact me directly.<div>',
|
|
151
|
+
"What Is My Username?"
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
function tokeninfo() {
|
|
155
|
+
showMessage(
|
|
156
|
+
'<div style="">The 2FA token or Auth token is required for SuperAdmin and NormalAdmin to log in. Each user has been given' +
|
|
157
|
+
' an Auth Code, which they can use to generate an Auth token using any Auth App.<div>',
|
|
158
|
+
"What Is Token?"
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
document.getElementById('loginForm').addEventListener('submit', function (event) {
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
const username = document.getElementById('loginUsername').value.trim();
|
|
165
|
+
const password = document.getElementById('loginPassword').value.trim();
|
|
166
|
+
const token = document.getElementById('token').value.trim(); // 2FA token
|
|
167
|
+
let recaptchaResponse;
|
|
168
|
+
|
|
169
|
+
recaptchaResponse = grecaptcha.getResponse();
|
|
170
|
+
|
|
171
|
+
if (!username || !password) {
|
|
172
|
+
showMessage("Username and password cannot be empty", "Error");
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const loginButton = document.querySelector('button[type="submit"]');
|
|
176
|
+
loginButton.disabled = true;
|
|
177
|
+
loginButton.innerText = "Logging in.....";
|
|
178
|
+
fetch('/mbkauthe/api/login', {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers: {
|
|
181
|
+
'Content-Type': 'application/json'
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify({ username, password, token, recaptcha: recaptchaResponse || null })
|
|
184
|
+
})
|
|
185
|
+
.then(response => {
|
|
186
|
+
loginButton.disabled = false;
|
|
187
|
+
loginButton.innerText = "Login";
|
|
188
|
+
return response.json().then(data => {
|
|
189
|
+
if (response.ok) {
|
|
190
|
+
return data;
|
|
191
|
+
} else {
|
|
192
|
+
throw new Error(data.message || "An error occurred");
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
})
|
|
196
|
+
.then(data => {
|
|
197
|
+
if (data.success) {
|
|
198
|
+
sessionStorage.setItem('sessionId', data.sessionId);
|
|
199
|
+
clearAllCookies();
|
|
200
|
+
const redirectUrl = new URLSearchParams(window.location.search).get('redirect');
|
|
201
|
+
loginButton.innerText = "Redirecting.....";
|
|
202
|
+
window.location.href = redirectUrl ? decodeURIComponent(redirectUrl) : '/chatbot';
|
|
203
|
+
} else {
|
|
204
|
+
grecaptcha.reset();
|
|
205
|
+
showMessage(data.message, "Error");
|
|
206
|
+
document.getElementById('loginMessage').innerText = data.message;
|
|
207
|
+
if (data.code === 401 && data.message === "Invalid 2FA code") {
|
|
208
|
+
console.log("data.message");
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
.catch(error => {
|
|
213
|
+
grecaptcha.reset();
|
|
214
|
+
if (error.message === "Please Enter 2FA code") {
|
|
215
|
+
showMessage("Please enter the 2FA code", "Error");
|
|
216
|
+
const tokenCon = document.getElementById('tokenCon');
|
|
217
|
+
const tokenInput = document.getElementById('token');
|
|
218
|
+
tokenCon.style.display = "block";
|
|
219
|
+
tokenInput.setAttribute('required', '');
|
|
220
|
+
} else {
|
|
221
|
+
console.error('Error:', error);
|
|
222
|
+
showMessage(error.message, "Error");
|
|
223
|
+
loginButton.disabled = false;
|
|
224
|
+
loginButton.innerText = "Login";
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
229
|
+
const loginButton = document.querySelector('button[type="submit"]');
|
|
230
|
+
loginButton.innerText = "Login";
|
|
231
|
+
});
|
|
232
|
+
// Event listener for toggling password visibility
|
|
233
|
+
document.addEventListener('DOMContentLoaded', function () { // Set the value of the input field with the page URL
|
|
234
|
+
const passwordInput = document.getElementById('loginPassword');
|
|
235
|
+
const toggleIcon = document.querySelector('.password-toggle-icon');
|
|
236
|
+
toggleIcon.addEventListener('click', function () { // Toggle the type of the input field
|
|
237
|
+
if (passwordInput.type === 'password') {
|
|
238
|
+
passwordInput.type = 'text'; // Show password
|
|
239
|
+
toggleIcon.innerHTML = '<i class="fa fa-eye-slash"></i>'; // Change icon to closed eye
|
|
240
|
+
} else {
|
|
241
|
+
passwordInput.type = 'password'; // Hide password
|
|
242
|
+
toggleIcon.innerHTML = '<i class="fa fa-eye"></i>'; // Change icon to open eye
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
247
|
+
const usernameFromUrl = urlParams.get('username');
|
|
248
|
+
const passwordFromUrl = urlParams.get('password');
|
|
249
|
+
if (usernameFromUrl && !document.getElementById('loginUsername').value) {
|
|
250
|
+
document.getElementById('loginUsername').value = usernameFromUrl;
|
|
251
|
+
}
|
|
252
|
+
if (passwordFromUrl && !document.getElementById('loginPassword').value) {
|
|
253
|
+
document.getElementById('loginPassword').value = passwordFromUrl;
|
|
254
|
+
}
|
|
255
|
+
</script>
|
|
256
|
+
|
|
257
|
+
</html>
|