mbkauthe 1.3.0 → 1.3.2
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 +1 -67
- package/lib/validateSessionAndRole.js +20 -7
- package/package.json +1 -1
- package/views/Error/dError.handlebars +37 -6
- package/views/info.handlebars +0 -142
- package/views/loginmbkauthe.handlebars +1 -1
package/lib/main.js
CHANGED
|
@@ -410,88 +410,22 @@ async function getLatestVersion() {
|
|
|
410
410
|
}
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
-
async function getPackageLock() {
|
|
414
|
-
const packageLockPath = path.resolve(process.cwd(), "package-lock.json");
|
|
415
|
-
|
|
416
|
-
return new Promise((resolve, reject) => {
|
|
417
|
-
fs.readFile(packageLockPath, "utf8", (err, data) => {
|
|
418
|
-
if (err) {
|
|
419
|
-
console.error("[mbkauthe] Error reading package-lock.json:", err);
|
|
420
|
-
return reject({ success: false, message: "Failed to read package-lock.json" });
|
|
421
|
-
}
|
|
422
|
-
try {
|
|
423
|
-
const packageLock = JSON.parse(data);
|
|
424
|
-
const mbkautheData = {
|
|
425
|
-
name: 'mbkauthe',
|
|
426
|
-
version: packageLock.packages['node_modules/mbkauthe']?.version || packageJson.version,
|
|
427
|
-
resolved: packageLock.packages['node_modules/mbkauthe']?.resolved || '',
|
|
428
|
-
integrity: packageLock.packages['node_modules/mbkauthe']?.integrity || '',
|
|
429
|
-
license: packageLock.packages['node_modules/mbkauthe']?.license || packageJson.license,
|
|
430
|
-
dependencies: packageLock.packages['node_modules/mbkauthe']?.dependencies || {}
|
|
431
|
-
};
|
|
432
|
-
const rootDependency = packageLock.dependencies?.mbkauthe || {};
|
|
433
|
-
resolve({ mbkautheData, rootDependency });
|
|
434
|
-
} catch (parseError) {
|
|
435
|
-
console.error("[mbkauthe] Error parsing package-lock.json:", parseError);
|
|
436
|
-
reject("Error parsing package-lock.json");
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
function formatJson(json) {
|
|
443
|
-
if (typeof json === 'string') {
|
|
444
|
-
try {
|
|
445
|
-
json = JSON.parse(json);
|
|
446
|
-
} catch (e) {
|
|
447
|
-
return json;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// First stringify with proper indentation
|
|
452
|
-
let jsonString = JSON.stringify(json, null, 2);
|
|
453
|
-
|
|
454
|
-
// Escape HTML special characters EXCEPT for our span tags
|
|
455
|
-
jsonString = jsonString
|
|
456
|
-
.replace(/&/g, '&')
|
|
457
|
-
.replace(/</g, '<')
|
|
458
|
-
.replace(/>/g, '>');
|
|
459
|
-
|
|
460
|
-
// Now apply syntax highlighting (after escaping)
|
|
461
|
-
jsonString = jsonString
|
|
462
|
-
// Highlight keys
|
|
463
|
-
.replace(/"([^"]+)":/g, '"<span style="color: #2b6cb0;">$1</span>":')
|
|
464
|
-
// Highlight string values
|
|
465
|
-
.replace(/:\s*"([^"]+)"/g, ': "<span style="color: #38a169;">$1</span>"')
|
|
466
|
-
// Highlight numbers
|
|
467
|
-
.replace(/: (\d+)/g, ': <span style="color: #dd6b20;">$1</span>')
|
|
468
|
-
// Highlight booleans and null
|
|
469
|
-
.replace(/: (true|false|null)/g, ': <span style="color: #805ad5;">$1</span>');
|
|
470
|
-
|
|
471
|
-
return jsonString;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
413
|
router.get(["/mbkauthe/info", "/mbkauthe/i"], LoginLimit, async (_, res) => {
|
|
475
|
-
let pkgl = {};
|
|
476
414
|
let latestVersion;
|
|
477
415
|
|
|
478
416
|
try {
|
|
479
|
-
pkgl = await getPackageLock();
|
|
480
417
|
latestVersion = await getLatestVersion();
|
|
481
418
|
//latestVersion = "Under Development"; // Placeholder for the latest version
|
|
482
419
|
} catch (err) {
|
|
483
420
|
console.error("[mbkauthe] Error fetching package-lock.json:", err);
|
|
484
|
-
pkgl = { error: "Failed to fetch package-lock.json" };
|
|
485
421
|
}
|
|
486
|
-
|
|
422
|
+
|
|
487
423
|
try {
|
|
488
424
|
res.render("info.handlebars", {
|
|
489
425
|
layout: false,
|
|
490
426
|
mbkautheVar: mbkautheVar,
|
|
491
427
|
version: packageJson.version,
|
|
492
428
|
latestVersion,
|
|
493
|
-
packageJson: packageJson.stringify,
|
|
494
|
-
packageLock: formatJson(pkgl),
|
|
495
429
|
});
|
|
496
430
|
} catch (err) {
|
|
497
431
|
console.error("[mbkauthe] Error fetching version information:", err);
|
|
@@ -113,7 +113,7 @@ async function validateSession(req, res, next) {
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
const checkRolePermission = (requiredRole) => {
|
|
116
|
+
const checkRolePermission = (requiredRole, notAllowed) => {
|
|
117
117
|
return async (req, res, next) => {
|
|
118
118
|
try {
|
|
119
119
|
if (!req.session || !req.session.user || !req.session.user.id) {
|
|
@@ -129,10 +129,6 @@ const checkRolePermission = (requiredRole) => {
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
if (requiredRole === "Any" || requiredRole === "any") {
|
|
133
|
-
return next();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
132
|
const userId = req.session.user.id;
|
|
137
133
|
|
|
138
134
|
const query = `SELECT "Role" FROM "Users" WHERE "id" = $1`;
|
|
@@ -143,6 +139,23 @@ const checkRolePermission = (requiredRole) => {
|
|
|
143
139
|
}
|
|
144
140
|
|
|
145
141
|
const userRole = result.rows[0].Role;
|
|
142
|
+
|
|
143
|
+
// Check notAllowed role
|
|
144
|
+
if (notAllowed && userRole === notAllowed) {
|
|
145
|
+
return res.render("Error/dError.handlebars", {
|
|
146
|
+
layout: false,
|
|
147
|
+
code: 403,
|
|
148
|
+
error: "Access Denied",
|
|
149
|
+
message: `You are not allowed to access this resource with role: ${notAllowed}`,
|
|
150
|
+
pagename: "Home",
|
|
151
|
+
page: `/${mbkautheVar.loginRedirectURL}`
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (requiredRole === "Any" || requiredRole === "any") {
|
|
156
|
+
return next();
|
|
157
|
+
}
|
|
158
|
+
|
|
146
159
|
if (userRole !== requiredRole) {
|
|
147
160
|
return res.render("Error/dError.handlebars", {
|
|
148
161
|
layout: false,
|
|
@@ -162,10 +175,10 @@ const checkRolePermission = (requiredRole) => {
|
|
|
162
175
|
};
|
|
163
176
|
};
|
|
164
177
|
|
|
165
|
-
const validateSessionAndRole = (requiredRole) => {
|
|
178
|
+
const validateSessionAndRole = (requiredRole, notAllowed) => {
|
|
166
179
|
return async (req, res, next) => {
|
|
167
180
|
await validateSession(req, res, async () => {
|
|
168
|
-
await checkRolePermission(requiredRole)(req, res, next);
|
|
181
|
+
await checkRolePermission(requiredRole, notAllowed)(req, res, next);
|
|
169
182
|
});
|
|
170
183
|
};
|
|
171
184
|
};
|
package/package.json
CHANGED
|
@@ -443,13 +443,11 @@
|
|
|
443
443
|
|
|
444
444
|
.status-box:hover {
|
|
445
445
|
box-shadow: var(--shadow-lg);
|
|
446
|
-
transform: scale(1.05);
|
|
447
446
|
}
|
|
448
447
|
|
|
449
448
|
.status-code {
|
|
450
449
|
text-align: center;
|
|
451
|
-
|
|
452
|
-
font-size: 2.5rem;
|
|
450
|
+
font-size: 4rem;
|
|
453
451
|
font-weight: 700;
|
|
454
452
|
color: var(--success);
|
|
455
453
|
position: relative;
|
|
@@ -465,7 +463,7 @@
|
|
|
465
463
|
.status-code::after {
|
|
466
464
|
content: '';
|
|
467
465
|
position: absolute;
|
|
468
|
-
bottom:
|
|
466
|
+
bottom: 10px;
|
|
469
467
|
left: 50%;
|
|
470
468
|
transform: translateX(-50%);
|
|
471
469
|
width: 100px;
|
|
@@ -502,7 +500,7 @@
|
|
|
502
500
|
|
|
503
501
|
.status-link:hover {
|
|
504
502
|
text-decoration: underline;
|
|
505
|
-
color:
|
|
503
|
+
color: #4057be;
|
|
506
504
|
}
|
|
507
505
|
|
|
508
506
|
.details-wrapper {
|
|
@@ -628,6 +626,35 @@
|
|
|
628
626
|
transform: translateY(-20px) rotate(5deg);
|
|
629
627
|
}
|
|
630
628
|
}
|
|
629
|
+
|
|
630
|
+
@media (max-width: 768px) {
|
|
631
|
+
|
|
632
|
+
.version-info {
|
|
633
|
+
bottom: 10px;
|
|
634
|
+
right: 10px;
|
|
635
|
+
font-size: 0.7rem;
|
|
636
|
+
padding: 6px 10px;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.version-info {
|
|
641
|
+
position: fixed;
|
|
642
|
+
bottom: 20px;
|
|
643
|
+
right: 20px;
|
|
644
|
+
background: var(--dark-light);
|
|
645
|
+
color: var(--gray);
|
|
646
|
+
padding: 8px 12px;
|
|
647
|
+
border-radius: var(--radius-sm);
|
|
648
|
+
font-size: 0.75rem;
|
|
649
|
+
border: 1px solid var(--glass-border);
|
|
650
|
+
z-index: 999;
|
|
651
|
+
transition: var(--transition);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.version-info:hover {
|
|
655
|
+
color: var(--primary);
|
|
656
|
+
border-color: var(--primary);
|
|
657
|
+
}
|
|
631
658
|
</style>
|
|
632
659
|
</head>
|
|
633
660
|
|
|
@@ -637,7 +664,7 @@
|
|
|
637
664
|
<div class="navbar">
|
|
638
665
|
<a class="logo">
|
|
639
666
|
<img src="https://mbktechstudio.com/Assets/Images/Icon/dgicon.svg" alt="MBK Tech Studio Logo">
|
|
640
|
-
<span class="logo-text">MBK Authe</span>
|
|
667
|
+
<span class="logo-text">{{#if app}}{{app}}{{else}}MBK Authe{{/if}}</span>
|
|
641
668
|
</a>
|
|
642
669
|
</div>
|
|
643
670
|
</nav>
|
|
@@ -683,6 +710,10 @@
|
|
|
683
710
|
|
|
684
711
|
</div>
|
|
685
712
|
</section>
|
|
713
|
+
<!-- Version Info -->
|
|
714
|
+
<div class="version-info">
|
|
715
|
+
v{{version}}
|
|
716
|
+
</div>
|
|
686
717
|
<script>
|
|
687
718
|
function toggleDetailsDropdown(element) {
|
|
688
719
|
const errorDetailsWrapper = element.querySelector('.error-details-wrapper');
|
package/views/info.handlebars
CHANGED
|
@@ -96,46 +96,6 @@
|
|
|
96
96
|
color: var(--text-color);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
.json-container {
|
|
100
|
-
background: #252525;
|
|
101
|
-
border: 1px solid var(--border-color);
|
|
102
|
-
border-radius: 6px;
|
|
103
|
-
padding: 12px;
|
|
104
|
-
margin-top: 10px;
|
|
105
|
-
max-height: 400px;
|
|
106
|
-
overflow: auto;
|
|
107
|
-
font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
|
|
108
|
-
font-size: 0.85em;
|
|
109
|
-
white-space: pre-wrap;
|
|
110
|
-
position: relative;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.json-container pre {
|
|
114
|
-
margin: 0;
|
|
115
|
-
font-family: inherit;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.json-container .key {
|
|
119
|
-
color: var(--key-color);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.json-container .string {
|
|
123
|
-
color: var(--string-color);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.json-container .number {
|
|
127
|
-
color: var(--number-color);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
.json-container .boolean {
|
|
131
|
-
color: var(--boolean-color);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.json-container .null {
|
|
135
|
-
color: var(--boolean-color);
|
|
136
|
-
opacity: 0.7;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
99
|
.version-status {
|
|
140
100
|
display: inline-block;
|
|
141
101
|
padding: 3px 10px;
|
|
@@ -163,30 +123,6 @@
|
|
|
163
123
|
border: 1px solid var(--warning);
|
|
164
124
|
}
|
|
165
125
|
|
|
166
|
-
.copy-btn {
|
|
167
|
-
background: var(--primary-dark);
|
|
168
|
-
color: white;
|
|
169
|
-
border: none;
|
|
170
|
-
padding: 5px 12px;
|
|
171
|
-
border-radius: 4px;
|
|
172
|
-
cursor: pointer;
|
|
173
|
-
font-size: 0.8em;
|
|
174
|
-
transition: all 0.2s ease;
|
|
175
|
-
display: flex;
|
|
176
|
-
align-items: center;
|
|
177
|
-
gap: 5px;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.copy-btn:hover {
|
|
181
|
-
background: var(--primary);
|
|
182
|
-
transform: translateY(-1px);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.copy-btn:active {
|
|
186
|
-
transform: translateY(0);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/* Scrollbar styling */
|
|
190
126
|
::-webkit-scrollbar {
|
|
191
127
|
width: 8px;
|
|
192
128
|
height: 8px;
|
|
@@ -293,86 +229,8 @@
|
|
|
293
229
|
</div>
|
|
294
230
|
</div>
|
|
295
231
|
|
|
296
|
-
<div class="info-section">
|
|
297
|
-
<h2>
|
|
298
|
-
Package Information
|
|
299
|
-
<button class="copy-btn tooltip" onclick="copyToClipboard('package-json')">
|
|
300
|
-
<span class="tooltiptext">Copy to clipboard</span>
|
|
301
|
-
Copy JSON
|
|
302
|
-
</button>
|
|
303
|
-
</h2>
|
|
304
|
-
<div id="package-json" class="json-container">
|
|
305
|
-
<pre>{{packageJson}}</pre>
|
|
306
|
-
</div>
|
|
307
|
-
</div>
|
|
308
|
-
|
|
309
|
-
<div class="info-section">
|
|
310
|
-
<h2>
|
|
311
|
-
Package Lock
|
|
312
|
-
<button class="copy-btn tooltip" onclick="copyToClipboard('package-lock')">
|
|
313
|
-
<span class="tooltiptext">Copy to clipboard</span>
|
|
314
|
-
Copy JSON
|
|
315
|
-
</button>
|
|
316
|
-
</h2>
|
|
317
|
-
<div id="package-lock" class="json-container">
|
|
318
|
-
<pre>{{packageLockJson}}</pre>
|
|
319
|
-
</div>
|
|
320
|
-
</div>
|
|
321
232
|
</div>
|
|
322
233
|
|
|
323
|
-
<script>
|
|
324
|
-
document.addEventListener('DOMContentLoaded', function () {
|
|
325
|
-
// Apply syntax highlighting to all JSON containers
|
|
326
|
-
const jsonContainers = document.querySelectorAll('.json-container pre');
|
|
327
|
-
jsonContainers.forEach(container => {
|
|
328
|
-
container.innerHTML = syntaxHighlight(container.textContent);
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
function syntaxHighlight(json) {
|
|
333
|
-
if (typeof json !== 'string') {
|
|
334
|
-
json = JSON.stringify(json, null, 2);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Escape HTML
|
|
338
|
-
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
339
|
-
|
|
340
|
-
// Apply syntax highlighting
|
|
341
|
-
return json.replace(
|
|
342
|
-
/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
|
|
343
|
-
function (match) {
|
|
344
|
-
let cls = 'number';
|
|
345
|
-
if (/^"/.test(match)) {
|
|
346
|
-
if (/:$/.test(match)) {
|
|
347
|
-
cls = 'key';
|
|
348
|
-
} else {
|
|
349
|
-
cls = 'string';
|
|
350
|
-
}
|
|
351
|
-
} else if (/true|false/.test(match)) {
|
|
352
|
-
cls = 'boolean';
|
|
353
|
-
} else if (/null/.test(match)) {
|
|
354
|
-
cls = 'null';
|
|
355
|
-
}
|
|
356
|
-
return '<span class="' + cls + '">' + match + '</span>';
|
|
357
|
-
}
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function copyToClipboard(elementId) {
|
|
362
|
-
const element = document.getElementById(elementId);
|
|
363
|
-
const text = element.textContent;
|
|
364
|
-
navigator.clipboard.writeText(text).then(() => {
|
|
365
|
-
const btn = element.parentElement.querySelector('.copy-btn');
|
|
366
|
-
const originalText = btn.innerHTML;
|
|
367
|
-
btn.innerHTML = '<span class="tooltiptext">Copied!</span>✓ Copied';
|
|
368
|
-
setTimeout(() => {
|
|
369
|
-
btn.innerHTML = '<span class="tooltiptext">Copy to clipboard</span>' + originalText.replace('✓ Copied', 'Copy JSON');
|
|
370
|
-
}, 2000);
|
|
371
|
-
}).catch(err => {
|
|
372
|
-
console.error('[mbkauthe] Failed to copy text: ', err);
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
</script>
|
|
376
234
|
</body>
|
|
377
235
|
|
|
378
236
|
</html>
|