mbkauthe 1.1.12 → 1.1.13

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  import express from "express"; // Add this line
2
2
  import router from "./lib/main.js";
3
- import { getLatestVersion } from "./lib/info.js";
3
+ import { getLatestVersion } from "./lib/main.js";
4
4
  import { engine } from "express-handlebars";
5
5
  import dotenv from "dotenv";
6
6
  import path from "path";
package/lib/main.js CHANGED
@@ -9,15 +9,23 @@ import fetch from 'node-fetch';
9
9
  import cookieParser from "cookie-parser";
10
10
  import bcrypt from 'bcrypt';
11
11
  import rateLimit from 'express-rate-limit';
12
- import mbkautheinfo from "./info.js";
13
12
  import speakeasy from "speakeasy";
14
13
 
14
+ import { createRequire } from "module";
15
+ import fs from "fs";
16
+ import path from "path";
17
+ import { marked } from "marked";
18
+ import * as cheerio from 'cheerio';
19
+
15
20
  import dotenv from "dotenv";
16
21
  dotenv.config();
17
22
  const mbkautheVar = JSON.parse(process.env.mbkautheVar);
18
23
 
19
24
  const router = express.Router();
20
25
 
26
+ const require = createRequire(import.meta.url);
27
+ const packageJson = require("../package.json");
28
+
21
29
  router.use(express.json());
22
30
  router.use(express.urlencoded({ extended: true }));
23
31
  router.use(cookieParser());
@@ -335,6 +343,507 @@ router.post("/mbkauthe/api/logout", async (req, res) => {
335
343
  }
336
344
  });
337
345
 
338
- router.use(mbkautheinfo);
339
346
 
347
+
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+
356
+
357
+
358
+
359
+
360
+
361
+
362
+ router.get("/mbkauthe/login", LoginLimit, (req, res) => {
363
+ return res.render("loginmbkauthe", {
364
+ layout: false,
365
+ customURL: mbkautheVar.loginRedirectURL || '/home',
366
+ userLoggedIn: !!req.session?.user,
367
+ username: req.session?.user?.username || ''
368
+ });
369
+ });
370
+
371
+ async function getLatestVersion() {
372
+ try {
373
+ const response = await fetch('https://raw.githubusercontent.com/MIbnEKhalid/mbkauthe/main/package.json');
374
+ if (!response.ok) {
375
+ throw new Error(`GitHub API responded with status ${response.status}`);
376
+ }
377
+ const latestPackageJson = await response.json();
378
+ return latestPackageJson.version;
379
+ } catch (error) {
380
+ console.error('Error fetching latest version from GitHub:', error);
381
+ return null;
382
+ }
383
+ }
384
+
385
+ async function getPackageLock() {
386
+ const packageLockPath = path.resolve(process.cwd(), "package-lock.json");
387
+
388
+ return new Promise((resolve, reject) => {
389
+ fs.readFile(packageLockPath, "utf8", (err, data) => {
390
+ if (err) {
391
+ console.error("Error reading package-lock.json:", err);
392
+ return reject({ success: false, message: "Failed to read package-lock.json" });
393
+ }
394
+ try {
395
+ const packageLock = JSON.parse(data);
396
+ const mbkautheData = {
397
+ name: 'mbkauthe',
398
+ version: packageLock.packages['node_modules/mbkauthe']?.version || packageJson.version,
399
+ resolved: packageLock.packages['node_modules/mbkauthe']?.resolved || '',
400
+ integrity: packageLock.packages['node_modules/mbkauthe']?.integrity || '',
401
+ license: packageLock.packages['node_modules/mbkauthe']?.license || packageJson.license,
402
+ dependencies: packageLock.packages['node_modules/mbkauthe']?.dependencies || {}
403
+ };
404
+ const rootDependency = packageLock.dependencies?.mbkauthe || {};
405
+ resolve({ mbkautheData, rootDependency });
406
+ } catch (parseError) {
407
+ console.error("Error parsing package-lock.json:", parseError);
408
+ reject("Error parsing package-lock.json");
409
+ }
410
+ });
411
+ });
412
+ }
413
+
414
+ function formatJson(json) {
415
+ if (typeof json === 'string') {
416
+ try {
417
+ json = JSON.parse(json);
418
+ } catch (e) {
419
+ return json;
420
+ }
421
+ }
422
+
423
+ // First stringify with proper indentation
424
+ let jsonString = JSON.stringify(json, null, 2);
425
+
426
+ // Escape HTML special characters EXCEPT for our span tags
427
+ jsonString = jsonString
428
+ .replace(/&/g, '&')
429
+ .replace(/</g, '&lt;')
430
+ .replace(/>/g, '&gt;');
431
+
432
+ // Now apply syntax highlighting (after escaping)
433
+ jsonString = jsonString
434
+ // Highlight keys
435
+ .replace(/"([^"]+)":/g, '"<span style="color: #2b6cb0;">$1</span>":')
436
+ // Highlight string values
437
+ .replace(/:\s*"([^"]+)"/g, ': "<span style="color: #38a169;">$1</span>"')
438
+ // Highlight numbers
439
+ .replace(/: (\d+)/g, ': <span style="color: #dd6b20;">$1</span>')
440
+ // Highlight booleans and null
441
+ .replace(/: (true|false|null)/g, ': <span style="color: #805ad5;">$1</span>');
442
+
443
+ return jsonString;
444
+ }
445
+
446
+ router.get(["/mbkauthe/info", "/mbkauthe/i"], LoginLimit, async (_, res) => {
447
+ let pkgl = {};
448
+ let latestVersion;
449
+
450
+ try {
451
+ pkgl = await getPackageLock();
452
+ latestVersion = await getLatestVersion();
453
+ //latestVersion = "Under Development"; // Placeholder for the latest version
454
+ } catch (err) {
455
+ console.error("Error fetching package-lock.json:", err);
456
+ pkgl = { error: "Failed to fetch package-lock.json" };
457
+ }
458
+
459
+ try {
460
+ res.status(200).send(`
461
+ <html>
462
+ <head>
463
+ <title>Version and Configuration Information</title>
464
+ <style>
465
+ :root {
466
+ --bg-color: #121212;
467
+ --card-bg: #1e1e1e;
468
+ --text-color: #e0e0e0;
469
+ --text-secondary: #a0a0a0;
470
+ --primary: #bb86fc;
471
+ --primary-dark: #3700b3;
472
+ --secondary: #03dac6;
473
+ --border-color: #333;
474
+ --success: #4caf50;
475
+ --warning: #ff9800;
476
+ --error: #f44336;
477
+ --key-color: #bb86fc;
478
+ --string-color: #03dac6;
479
+ --number-color: #ff7043;
480
+ --boolean-color: #7986cb;
481
+ }
482
+
483
+ body {
484
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
485
+ margin: 0;
486
+ padding: 20px;
487
+ background-color: var(--bg-color);
488
+ color: var(--text-color);
489
+ }
490
+
491
+ .container {
492
+ max-width: 1000px;
493
+ margin: 0 auto;
494
+ padding: 20px;
495
+ background: var(--card-bg);
496
+ border-radius: 8px;
497
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
498
+ }
499
+
500
+ h1 {
501
+ color: var(--primary);
502
+ text-align: center;
503
+ margin-bottom: 30px;
504
+ padding-bottom: 10px;
505
+ border-bottom: 1px solid var(--border-color);
506
+ font-weight: bold;
507
+ letter-spacing: 1px;
508
+ }
509
+
510
+ .info-section {
511
+ margin-bottom: 25px;
512
+ padding: 20px;
513
+ border: 1px solid var(--border-color);
514
+ border-radius: 8px;
515
+ background-color: rgba(30, 30, 30, 0.7);
516
+ transition: all 0.3s ease;
517
+ }
518
+
519
+ .info-section:hover {
520
+ border-color: var(--primary);
521
+ box-shadow: 0 0 0 1px var(--primary);
522
+ }
523
+
524
+ .info-section h2 {
525
+ color: var(--primary);
526
+ border-bottom: 2px solid var(--primary-dark);
527
+ padding-bottom: 8px;
528
+ margin-top: 0;
529
+ margin-bottom: 15px;
530
+ font-size: 1.2em;
531
+ display: flex;
532
+ justify-content: space-between;
533
+ align-items: center;
534
+ }
535
+
536
+ .info-row {
537
+ display: flex;
538
+ margin-bottom: 10px;
539
+ padding-bottom: 10px;
540
+ border-bottom: 1px solid var(--border-color);
541
+ }
542
+
543
+ .info-label {
544
+ font-weight: 600;
545
+ color: var(--text-secondary);
546
+ min-width: 220px;
547
+ font-size: 0.95em;
548
+ }
549
+
550
+ .info-value {
551
+ flex: 1;
552
+ word-break: break-word;
553
+ color: var(--text-color);
554
+ }
555
+
556
+ .json-container {
557
+ background: #252525;
558
+ border: 1px solid var(--border-color);
559
+ border-radius: 6px;
560
+ padding: 12px;
561
+ margin-top: 10px;
562
+ max-height: 400px;
563
+ overflow: auto;
564
+ font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
565
+ font-size: 0.85em;
566
+ white-space: pre-wrap;
567
+ position: relative;
568
+ }
569
+
570
+ .json-container pre {
571
+ margin: 0;
572
+ font-family: inherit;
573
+ }
574
+
575
+ .json-container .key {
576
+ color: var(--key-color);
577
+ }
578
+
579
+ .json-container .string {
580
+ color: var(--string-color);
581
+ }
582
+
583
+ .json-container .number {
584
+ color: var(--number-color);
585
+ }
586
+
587
+ .json-container .boolean {
588
+ color: var(--boolean-color);
589
+ }
590
+
591
+ .json-container .null {
592
+ color: var(--boolean-color);
593
+ opacity: 0.7;
594
+ }
595
+
596
+ .version-status {
597
+ display: inline-block;
598
+ padding: 3px 10px;
599
+ border-radius: 12px;
600
+ font-size: 0.8em;
601
+ font-weight: 600;
602
+ margin-left: 10px;
603
+ }
604
+
605
+ .version-up-to-date {
606
+ background: rgba(76, 175, 80, 0.2);
607
+ color: var(--success);
608
+ border: 1px solid var(--success);
609
+ }
610
+
611
+ .version-outdated {
612
+ background: rgba(244, 67, 54, 0.2);
613
+ color: var(--error);
614
+ border: 1px solid var(--error);
615
+ }
616
+
617
+ .version-fetch-error {
618
+ background: rgba(255, 152, 0, 0.2);
619
+ color: var(--warning);
620
+ border: 1px solid var(--warning);
621
+ }
622
+
623
+ .copy-btn {
624
+ background: var(--primary-dark);
625
+ color: white;
626
+ border: none;
627
+ padding: 5px 12px;
628
+ border-radius: 4px;
629
+ cursor: pointer;
630
+ font-size: 0.8em;
631
+ transition: all 0.2s ease;
632
+ display: flex;
633
+ align-items: center;
634
+ gap: 5px;
635
+ }
636
+
637
+ .copy-btn:hover {
638
+ background: var(--primary);
639
+ transform: translateY(-1px);
640
+ }
641
+
642
+ .copy-btn:active {
643
+ transform: translateY(0);
644
+ }
645
+
646
+ /* Scrollbar styling */
647
+ ::-webkit-scrollbar {
648
+ width: 8px;
649
+ height: 8px;
650
+ }
651
+
652
+ ::-webkit-scrollbar-track {
653
+ background: #2d2d2d;
654
+ border-radius: 4px;
655
+ }
656
+
657
+ ::-webkit-scrollbar-thumb {
658
+ background: #555;
659
+ border-radius: 4px;
660
+ }
661
+
662
+ ::-webkit-scrollbar-thumb:hover {
663
+ background: var(--primary);
664
+ }
665
+
666
+ /* Tooltip for copy button */
667
+ .tooltip {
668
+ position: relative;
669
+ display: inline-block;
670
+ }
671
+
672
+ .tooltip .tooltiptext {
673
+ visibility: hidden;
674
+ width: 120px;
675
+ background-color: #333;
676
+ color: #fff;
677
+ text-align: center;
678
+ border-radius: 6px;
679
+ padding: 5px;
680
+ position: absolute;
681
+ z-index: 1;
682
+ bottom: 125%;
683
+ left: 50%;
684
+ margin-left: -60px;
685
+ opacity: 0;
686
+ transition: opacity 0.3s;
687
+ font-size: 0.8em;
688
+ }
689
+
690
+ .tooltip:hover .tooltiptext {
691
+ visibility: visible;
692
+ opacity: 1;
693
+ }
694
+ </style>
695
+ <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
696
+ </head>
697
+
698
+ <body>
699
+ <div class="container">
700
+ <h1>Version and Configuration Dashboard</h1>
701
+
702
+ <div class="info-section">
703
+ <h2>Version Information</h2>
704
+ <div class="info-row">
705
+ <div class="info-label">Current Version:</div>
706
+ <div class="info-value">${packageJson.version}</div>
707
+ </div>
708
+ <div class="info-row">
709
+ <div class="info-label">Latest Version:</div>
710
+ <div class="info-value">
711
+ ${latestVersion || 'Could not fetch latest version'}
712
+ ${latestVersion ? `
713
+ <span class="version-status ${packageJson.version === latestVersion ? 'version-up-to-date' : 'version-outdated'}">
714
+ ${packageJson.version === latestVersion ? 'Up to date' : 'Update available'}
715
+ </span>
716
+ ` : `
717
+ <span class="version-status version-fetch-error">
718
+ Fetch error
719
+ </span>
720
+ `}
721
+ </div>
722
+ </div>
723
+ </div>
724
+
725
+ <div class="info-section">
726
+ <h2>Configuration Information</h2>
727
+ <div class="info-row">
728
+ <div class="info-label">APP_NAME:</div>
729
+ <div class="info-value">${mbkautheVar.APP_NAME}</div>
730
+ </div>
731
+ <div class="info-row">
732
+ <div class="info-label">RECAPTCHA_Enabled:</div>
733
+ <div class="info-value">${mbkautheVar.RECAPTCHA_Enabled}</div>
734
+ </div>
735
+ <div class="info-row">
736
+ <div class="info-label">MBKAUTH_TWO_FA_ENABLE:</div>
737
+ <div class="info-value">${mbkautheVar.MBKAUTH_TWO_FA_ENABLE}</div>
738
+ </div>
739
+ <div class="info-row">
740
+ <div class="info-label">COOKIE_EXPIRE_TIME:</div>
741
+ <div class="info-value">${mbkautheVar.COOKIE_EXPIRE_TIME} Days</div>
742
+ </div>
743
+ <div class="info-row">
744
+ <div class="info-label">IS_DEPLOYED:</div>
745
+ <div class="info-value">${mbkautheVar.IS_DEPLOYED}</div>
746
+ </div>
747
+ <div class="info-row">
748
+ <div class="info-label">DOMAIN:</div>
749
+ <div class="info-value">${mbkautheVar.DOMAIN}</div>
750
+ </div>
751
+ </div>
752
+
753
+ <div class="info-section">
754
+ <h2>
755
+ Package Information
756
+ <button class="copy-btn tooltip" onclick="copyToClipboard('package-json')">
757
+ <span class="tooltiptext">Copy to clipboard</span>
758
+ Copy JSON
759
+ </button>
760
+ </h2>
761
+ <div id="package-json" class="json-container"><pre>${JSON.stringify(packageJson, null, 2)}</pre></div>
762
+ </div>
763
+
764
+ <div class="info-section">
765
+ <h2>
766
+ Package Lock
767
+ <button class="copy-btn tooltip" onclick="copyToClipboard('package-lock')">
768
+ <span class="tooltiptext">Copy to clipboard</span>
769
+ Copy JSON
770
+ </button>
771
+ </h2>
772
+ <div id="package-lock" class="json-container"><pre>${JSON.stringify(pkgl, null, 2)}</pre></div>
773
+ </div>
774
+ </div>
775
+
776
+ <script>
777
+ document.addEventListener('DOMContentLoaded', function() {
778
+ // Apply syntax highlighting to all JSON containers
779
+ const jsonContainers = document.querySelectorAll('.json-container pre');
780
+ jsonContainers.forEach(container => {
781
+ container.innerHTML = syntaxHighlight(container.textContent);
782
+ });
783
+ });
784
+
785
+ function syntaxHighlight(json) {
786
+ if (typeof json !== 'string') {
787
+ json = JSON.stringify(json, null, 2);
788
+ }
789
+
790
+ // Escape HTML
791
+ json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
792
+
793
+ // Apply syntax highlighting
794
+ return json.replace(
795
+ /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
796
+ function(match) {
797
+ let cls = 'number';
798
+ if (/^"/.test(match)) {
799
+ if (/:$/.test(match)) {
800
+ cls = 'key';
801
+ } else {
802
+ cls = 'string';
803
+ }
804
+ } else if (/true|false/.test(match)) {
805
+ cls = 'boolean';
806
+ } else if (/null/.test(match)) {
807
+ cls = 'null';
808
+ }
809
+ return '<span class="' + cls + '">' + match + '</span>';
810
+ }
811
+ );
812
+ }
813
+
814
+ function copyToClipboard(elementId) {
815
+ const element = document.getElementById(elementId);
816
+ const text = element.textContent;
817
+ navigator.clipboard.writeText(text).then(() => {
818
+ const btn = element.parentElement.querySelector('.copy-btn');
819
+ const originalText = btn.innerHTML;
820
+ btn.innerHTML = '<span class="tooltiptext">Copied!</span>✓ Copied';
821
+ setTimeout(() => {
822
+ btn.innerHTML = '<span class="tooltiptext">Copy to clipboard</span>' + originalText.replace('✓ Copied', 'Copy JSON');
823
+ }, 2000);
824
+ }).catch(err => {
825
+ console.error('Failed to copy text: ', err);
826
+ });
827
+ }
828
+ </script>
829
+ </body>
830
+ </html>
831
+ `);
832
+ } catch (err) {
833
+ console.error("Error fetching version information:", err);
834
+ res.status(500).send(`
835
+ <html>
836
+ <head>
837
+ <title>Error</title>
838
+ </head>
839
+ <body>
840
+ <h1>Error</h1>
841
+ <p>Failed to fetch version information. Please try again later.</p>
842
+ </body>
843
+ </html>
844
+ `);
845
+ }
846
+ });
847
+
848
+ export { getLatestVersion };
340
849
  export default router;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mbkauthe",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "MBKTechStudio's reusable authentication system for Node.js applications.",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/lib/info.js DELETED
@@ -1,505 +0,0 @@
1
- import express from "express";
2
- import fetch from 'node-fetch';
3
- import { createRequire } from "module";
4
- import fs from "fs";
5
- import path from "path";
6
- import { marked } from "marked";
7
- import * as cheerio from 'cheerio';
8
-
9
- const require = createRequire(import.meta.url);
10
- const packageJson = require("../package.json");
11
-
12
- import dotenv from "dotenv";
13
- dotenv.config();
14
- const mbkautheVar = JSON.parse(process.env.mbkautheVar);
15
-
16
- const router = express.Router();
17
-
18
- router.get("/mbkauthe/login", (req, res) => {
19
- return res.render("loginmbkauthe", {
20
- layout: false,
21
- customURL: mbkautheVar.loginRedirectURL || '/home',
22
- userLoggedIn: !!req.session?.user,
23
- username: req.session?.user?.username || ''
24
- });
25
- });
26
-
27
- async function getLatestVersion() {
28
- try {
29
- const response = await fetch('https://raw.githubusercontent.com/MIbnEKhalid/mbkauthe/main/package.json');
30
- if (!response.ok) {
31
- throw new Error(`GitHub API responded with status ${response.status}`);
32
- }
33
- const latestPackageJson = await response.json();
34
- return latestPackageJson.version;
35
- } catch (error) {
36
- console.error('Error fetching latest version from GitHub:', error);
37
- return null;
38
- }
39
- }
40
-
41
- async function getPackageLock() {
42
- const packageLockPath = path.resolve(process.cwd(), "package-lock.json");
43
-
44
- return new Promise((resolve, reject) => {
45
- fs.readFile(packageLockPath, "utf8", (err, data) => {
46
- if (err) {
47
- console.error("Error reading package-lock.json:", err);
48
- return reject({ success: false, message: "Failed to read package-lock.json" });
49
- }
50
- try {
51
- const packageLock = JSON.parse(data);
52
- const mbkautheData = {
53
- name: 'mbkauthe',
54
- version: packageLock.packages['node_modules/mbkauthe']?.version || packageJson.version,
55
- resolved: packageLock.packages['node_modules/mbkauthe']?.resolved || '',
56
- integrity: packageLock.packages['node_modules/mbkauthe']?.integrity || '',
57
- license: packageLock.packages['node_modules/mbkauthe']?.license || packageJson.license,
58
- dependencies: packageLock.packages['node_modules/mbkauthe']?.dependencies || {}
59
- };
60
- const rootDependency = packageLock.dependencies?.mbkauthe || {};
61
- resolve({ mbkautheData, rootDependency });
62
- } catch (parseError) {
63
- console.error("Error parsing package-lock.json:", parseError);
64
- reject("Error parsing package-lock.json");
65
- }
66
- });
67
- });
68
- }
69
-
70
- function formatJson(json) {
71
- if (typeof json === 'string') {
72
- try {
73
- json = JSON.parse(json);
74
- } catch (e) {
75
- return json;
76
- }
77
- }
78
-
79
- // First stringify with proper indentation
80
- let jsonString = JSON.stringify(json, null, 2);
81
-
82
- // Escape HTML special characters EXCEPT for our span tags
83
- jsonString = jsonString
84
- .replace(/&/g, '&amp;')
85
- .replace(/</g, '&lt;')
86
- .replace(/>/g, '&gt;');
87
-
88
- // Now apply syntax highlighting (after escaping)
89
- jsonString = jsonString
90
- // Highlight keys
91
- .replace(/"([^"]+)":/g, '"<span style="color: #2b6cb0;">$1</span>":')
92
- // Highlight string values
93
- .replace(/:\s*"([^"]+)"/g, ': "<span style="color: #38a169;">$1</span>"')
94
- // Highlight numbers
95
- .replace(/: (\d+)/g, ': <span style="color: #dd6b20;">$1</span>')
96
- // Highlight booleans and null
97
- .replace(/: (true|false|null)/g, ': <span style="color: #805ad5;">$1</span>');
98
-
99
- return jsonString;
100
- }
101
-
102
- router.get(["/mbkauthe/info", "/mbkauthe/i"], async (_, res) => {
103
- let pkgl = {};
104
- let latestVersion;
105
-
106
- try {
107
- pkgl = await getPackageLock();
108
- latestVersion = await getLatestVersion();
109
- //latestVersion = "Under Development"; // Placeholder for the latest version
110
- } catch (err) {
111
- console.error("Error fetching package-lock.json:", err);
112
- pkgl = { error: "Failed to fetch package-lock.json" };
113
- }
114
-
115
- try {
116
- res.status(200).send(`
117
- <html>
118
- <head>
119
- <title>Version and Configuration Information</title>
120
- <style>
121
- :root {
122
- --bg-color: #121212;
123
- --card-bg: #1e1e1e;
124
- --text-color: #e0e0e0;
125
- --text-secondary: #a0a0a0;
126
- --primary: #bb86fc;
127
- --primary-dark: #3700b3;
128
- --secondary: #03dac6;
129
- --border-color: #333;
130
- --success: #4caf50;
131
- --warning: #ff9800;
132
- --error: #f44336;
133
- --key-color: #bb86fc;
134
- --string-color: #03dac6;
135
- --number-color: #ff7043;
136
- --boolean-color: #7986cb;
137
- }
138
-
139
- body {
140
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
141
- margin: 0;
142
- padding: 20px;
143
- background-color: var(--bg-color);
144
- color: var(--text-color);
145
- }
146
-
147
- .container {
148
- max-width: 1000px;
149
- margin: 0 auto;
150
- padding: 20px;
151
- background: var(--card-bg);
152
- border-radius: 8px;
153
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
154
- }
155
-
156
- h1 {
157
- color: var(--primary);
158
- text-align: center;
159
- margin-bottom: 30px;
160
- padding-bottom: 10px;
161
- border-bottom: 1px solid var(--border-color);
162
- font-weight: bold;
163
- letter-spacing: 1px;
164
- }
165
-
166
- .info-section {
167
- margin-bottom: 25px;
168
- padding: 20px;
169
- border: 1px solid var(--border-color);
170
- border-radius: 8px;
171
- background-color: rgba(30, 30, 30, 0.7);
172
- transition: all 0.3s ease;
173
- }
174
-
175
- .info-section:hover {
176
- border-color: var(--primary);
177
- box-shadow: 0 0 0 1px var(--primary);
178
- }
179
-
180
- .info-section h2 {
181
- color: var(--primary);
182
- border-bottom: 2px solid var(--primary-dark);
183
- padding-bottom: 8px;
184
- margin-top: 0;
185
- margin-bottom: 15px;
186
- font-size: 1.2em;
187
- display: flex;
188
- justify-content: space-between;
189
- align-items: center;
190
- }
191
-
192
- .info-row {
193
- display: flex;
194
- margin-bottom: 10px;
195
- padding-bottom: 10px;
196
- border-bottom: 1px solid var(--border-color);
197
- }
198
-
199
- .info-label {
200
- font-weight: 600;
201
- color: var(--text-secondary);
202
- min-width: 220px;
203
- font-size: 0.95em;
204
- }
205
-
206
- .info-value {
207
- flex: 1;
208
- word-break: break-word;
209
- color: var(--text-color);
210
- }
211
-
212
- .json-container {
213
- background: #252525;
214
- border: 1px solid var(--border-color);
215
- border-radius: 6px;
216
- padding: 12px;
217
- margin-top: 10px;
218
- max-height: 400px;
219
- overflow: auto;
220
- font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
221
- font-size: 0.85em;
222
- white-space: pre-wrap;
223
- position: relative;
224
- }
225
-
226
- .json-container pre {
227
- margin: 0;
228
- font-family: inherit;
229
- }
230
-
231
- .json-container .key {
232
- color: var(--key-color);
233
- }
234
-
235
- .json-container .string {
236
- color: var(--string-color);
237
- }
238
-
239
- .json-container .number {
240
- color: var(--number-color);
241
- }
242
-
243
- .json-container .boolean {
244
- color: var(--boolean-color);
245
- }
246
-
247
- .json-container .null {
248
- color: var(--boolean-color);
249
- opacity: 0.7;
250
- }
251
-
252
- .version-status {
253
- display: inline-block;
254
- padding: 3px 10px;
255
- border-radius: 12px;
256
- font-size: 0.8em;
257
- font-weight: 600;
258
- margin-left: 10px;
259
- }
260
-
261
- .version-up-to-date {
262
- background: rgba(76, 175, 80, 0.2);
263
- color: var(--success);
264
- border: 1px solid var(--success);
265
- }
266
-
267
- .version-outdated {
268
- background: rgba(244, 67, 54, 0.2);
269
- color: var(--error);
270
- border: 1px solid var(--error);
271
- }
272
-
273
- .version-fetch-error {
274
- background: rgba(255, 152, 0, 0.2);
275
- color: var(--warning);
276
- border: 1px solid var(--warning);
277
- }
278
-
279
- .copy-btn {
280
- background: var(--primary-dark);
281
- color: white;
282
- border: none;
283
- padding: 5px 12px;
284
- border-radius: 4px;
285
- cursor: pointer;
286
- font-size: 0.8em;
287
- transition: all 0.2s ease;
288
- display: flex;
289
- align-items: center;
290
- gap: 5px;
291
- }
292
-
293
- .copy-btn:hover {
294
- background: var(--primary);
295
- transform: translateY(-1px);
296
- }
297
-
298
- .copy-btn:active {
299
- transform: translateY(0);
300
- }
301
-
302
- /* Scrollbar styling */
303
- ::-webkit-scrollbar {
304
- width: 8px;
305
- height: 8px;
306
- }
307
-
308
- ::-webkit-scrollbar-track {
309
- background: #2d2d2d;
310
- border-radius: 4px;
311
- }
312
-
313
- ::-webkit-scrollbar-thumb {
314
- background: #555;
315
- border-radius: 4px;
316
- }
317
-
318
- ::-webkit-scrollbar-thumb:hover {
319
- background: var(--primary);
320
- }
321
-
322
- /* Tooltip for copy button */
323
- .tooltip {
324
- position: relative;
325
- display: inline-block;
326
- }
327
-
328
- .tooltip .tooltiptext {
329
- visibility: hidden;
330
- width: 120px;
331
- background-color: #333;
332
- color: #fff;
333
- text-align: center;
334
- border-radius: 6px;
335
- padding: 5px;
336
- position: absolute;
337
- z-index: 1;
338
- bottom: 125%;
339
- left: 50%;
340
- margin-left: -60px;
341
- opacity: 0;
342
- transition: opacity 0.3s;
343
- font-size: 0.8em;
344
- }
345
-
346
- .tooltip:hover .tooltiptext {
347
- visibility: visible;
348
- opacity: 1;
349
- }
350
- </style>
351
- <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
352
- </head>
353
-
354
- <body>
355
- <div class="container">
356
- <h1>Version and Configuration Dashboard</h1>
357
-
358
- <div class="info-section">
359
- <h2>Version Information</h2>
360
- <div class="info-row">
361
- <div class="info-label">Current Version:</div>
362
- <div class="info-value">${packageJson.version}</div>
363
- </div>
364
- <div class="info-row">
365
- <div class="info-label">Latest Version:</div>
366
- <div class="info-value">
367
- ${latestVersion || 'Could not fetch latest version'}
368
- ${latestVersion ? `
369
- <span class="version-status ${packageJson.version === latestVersion ? 'version-up-to-date' : 'version-outdated'}">
370
- ${packageJson.version === latestVersion ? 'Up to date' : 'Update available'}
371
- </span>
372
- ` : `
373
- <span class="version-status version-fetch-error">
374
- Fetch error
375
- </span>
376
- `}
377
- </div>
378
- </div>
379
- </div>
380
-
381
- <div class="info-section">
382
- <h2>Configuration Information</h2>
383
- <div class="info-row">
384
- <div class="info-label">APP_NAME:</div>
385
- <div class="info-value">${mbkautheVar.APP_NAME}</div>
386
- </div>
387
- <div class="info-row">
388
- <div class="info-label">RECAPTCHA_Enabled:</div>
389
- <div class="info-value">${mbkautheVar.RECAPTCHA_Enabled}</div>
390
- </div>
391
- <div class="info-row">
392
- <div class="info-label">MBKAUTH_TWO_FA_ENABLE:</div>
393
- <div class="info-value">${mbkautheVar.MBKAUTH_TWO_FA_ENABLE}</div>
394
- </div>
395
- <div class="info-row">
396
- <div class="info-label">COOKIE_EXPIRE_TIME:</div>
397
- <div class="info-value">${mbkautheVar.COOKIE_EXPIRE_TIME} Days</div>
398
- </div>
399
- <div class="info-row">
400
- <div class="info-label">IS_DEPLOYED:</div>
401
- <div class="info-value">${mbkautheVar.IS_DEPLOYED}</div>
402
- </div>
403
- <div class="info-row">
404
- <div class="info-label">DOMAIN:</div>
405
- <div class="info-value">${mbkautheVar.DOMAIN}</div>
406
- </div>
407
- </div>
408
-
409
- <div class="info-section">
410
- <h2>
411
- Package Information
412
- <button class="copy-btn tooltip" onclick="copyToClipboard('package-json')">
413
- <span class="tooltiptext">Copy to clipboard</span>
414
- Copy JSON
415
- </button>
416
- </h2>
417
- <div id="package-json" class="json-container"><pre>${JSON.stringify(packageJson, null, 2)}</pre></div>
418
- </div>
419
-
420
- <div class="info-section">
421
- <h2>
422
- Package Lock
423
- <button class="copy-btn tooltip" onclick="copyToClipboard('package-lock')">
424
- <span class="tooltiptext">Copy to clipboard</span>
425
- Copy JSON
426
- </button>
427
- </h2>
428
- <div id="package-lock" class="json-container"><pre>${JSON.stringify(pkgl, null, 2)}</pre></div>
429
- </div>
430
- </div>
431
-
432
- <script>
433
- document.addEventListener('DOMContentLoaded', function() {
434
- // Apply syntax highlighting to all JSON containers
435
- const jsonContainers = document.querySelectorAll('.json-container pre');
436
- jsonContainers.forEach(container => {
437
- container.innerHTML = syntaxHighlight(container.textContent);
438
- });
439
- });
440
-
441
- function syntaxHighlight(json) {
442
- if (typeof json !== 'string') {
443
- json = JSON.stringify(json, null, 2);
444
- }
445
-
446
- // Escape HTML
447
- json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
448
-
449
- // Apply syntax highlighting
450
- return json.replace(
451
- /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
452
- function(match) {
453
- let cls = 'number';
454
- if (/^"/.test(match)) {
455
- if (/:$/.test(match)) {
456
- cls = 'key';
457
- } else {
458
- cls = 'string';
459
- }
460
- } else if (/true|false/.test(match)) {
461
- cls = 'boolean';
462
- } else if (/null/.test(match)) {
463
- cls = 'null';
464
- }
465
- return '<span class="' + cls + '">' + match + '</span>';
466
- }
467
- );
468
- }
469
-
470
- function copyToClipboard(elementId) {
471
- const element = document.getElementById(elementId);
472
- const text = element.textContent;
473
- navigator.clipboard.writeText(text).then(() => {
474
- const btn = element.parentElement.querySelector('.copy-btn');
475
- const originalText = btn.innerHTML;
476
- btn.innerHTML = '<span class="tooltiptext">Copied!</span>✓ Copied';
477
- setTimeout(() => {
478
- btn.innerHTML = '<span class="tooltiptext">Copy to clipboard</span>' + originalText.replace('✓ Copied', 'Copy JSON');
479
- }, 2000);
480
- }).catch(err => {
481
- console.error('Failed to copy text: ', err);
482
- });
483
- }
484
- </script>
485
- </body>
486
- </html>
487
- `);
488
- } catch (err) {
489
- console.error("Error fetching version information:", err);
490
- res.status(500).send(`
491
- <html>
492
- <head>
493
- <title>Error</title>
494
- </head>
495
- <body>
496
- <h1>Error</h1>
497
- <p>Failed to fetch version information. Please try again later.</p>
498
- </body>
499
- </html>
500
- `);
501
- }
502
- });
503
-
504
- export { getLatestVersion };
505
- export default router;