mbkauthe 1.1.12 → 1.1.14

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
@@ -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());
@@ -136,36 +144,9 @@ router.post("/mbkauthe/api/terminateAllSessions", authenticate(mbkautheVar.Main_
136
144
  router.post("/mbkauthe/api/login", LoginLimit, async (req, res) => {
137
145
  console.log("Login request received");
138
146
 
139
- const { username, password, token, recaptcha } = req.body;
147
+ const { username, password, token } = req.body;
140
148
  console.log(`Login attempt for username: ${username}`);
141
149
 
142
- const secretKey = mbkautheVar.RECAPTCHA_SECRET_KEY;
143
- const verificationUrl = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${recaptcha}`;
144
-
145
- let BypassUsers = Array.isArray(mbkautheVar.BypassUsers) ? mbkautheVar.BypassUsers : JSON.parse(mbkautheVar.BypassUsers);
146
-
147
- if (mbkautheVar.RECAPTCHA_Enabled === "true") {
148
- if (!BypassUsers.includes(username)) {
149
- if (!recaptcha) {
150
- console.log("Missing reCAPTCHA token");
151
- return res.status(400).json({ success: false, message: "Please complete the reCAPTCHA" });
152
- }
153
- try {
154
- const response = await fetch(verificationUrl, { method: 'POST' });
155
- const body = await response.json();
156
- console.log("reCAPTCHA verification response:", body);
157
-
158
- if (!body.success) {
159
- console.log("Failed reCAPTCHA verification");
160
- return res.status(400).json({ success: false, message: "Failed reCAPTCHA verification" });
161
- }
162
- } catch (err) {
163
- console.log("Error during reCAPTCHA verification:", err);
164
- return res.status(500).json({ success: false, message: "Internal Server Error" });
165
- }
166
- }
167
- }
168
-
169
150
  if (!username || !password) {
170
151
  console.log("Missing username or password");
171
152
  return res.status(400).json({
@@ -335,6 +316,503 @@ router.post("/mbkauthe/api/logout", async (req, res) => {
335
316
  }
336
317
  });
337
318
 
338
- router.use(mbkautheinfo);
339
319
 
320
+
321
+
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
330
+
331
+
332
+
333
+
334
+
335
+ router.get("/mbkauthe/login", LoginLimit, (req, res) => {
336
+ return res.render("loginmbkauthe", {
337
+ layout: false,
338
+ customURL: mbkautheVar.loginRedirectURL || '/home',
339
+ userLoggedIn: !!req.session?.user,
340
+ username: req.session?.user?.username || ''
341
+ });
342
+ });
343
+
344
+ async function getLatestVersion() {
345
+ try {
346
+ const response = await fetch('https://raw.githubusercontent.com/MIbnEKhalid/mbkauthe/main/package.json');
347
+ if (!response.ok) {
348
+ throw new Error(`GitHub API responded with status ${response.status}`);
349
+ }
350
+ const latestPackageJson = await response.json();
351
+ return latestPackageJson.version;
352
+ } catch (error) {
353
+ console.error('Error fetching latest version from GitHub:', error);
354
+ return null;
355
+ }
356
+ }
357
+
358
+ async function getPackageLock() {
359
+ const packageLockPath = path.resolve(process.cwd(), "package-lock.json");
360
+
361
+ return new Promise((resolve, reject) => {
362
+ fs.readFile(packageLockPath, "utf8", (err, data) => {
363
+ if (err) {
364
+ console.error("Error reading package-lock.json:", err);
365
+ return reject({ success: false, message: "Failed to read package-lock.json" });
366
+ }
367
+ try {
368
+ const packageLock = JSON.parse(data);
369
+ const mbkautheData = {
370
+ name: 'mbkauthe',
371
+ version: packageLock.packages['node_modules/mbkauthe']?.version || packageJson.version,
372
+ resolved: packageLock.packages['node_modules/mbkauthe']?.resolved || '',
373
+ integrity: packageLock.packages['node_modules/mbkauthe']?.integrity || '',
374
+ license: packageLock.packages['node_modules/mbkauthe']?.license || packageJson.license,
375
+ dependencies: packageLock.packages['node_modules/mbkauthe']?.dependencies || {}
376
+ };
377
+ const rootDependency = packageLock.dependencies?.mbkauthe || {};
378
+ resolve({ mbkautheData, rootDependency });
379
+ } catch (parseError) {
380
+ console.error("Error parsing package-lock.json:", parseError);
381
+ reject("Error parsing package-lock.json");
382
+ }
383
+ });
384
+ });
385
+ }
386
+
387
+ function formatJson(json) {
388
+ if (typeof json === 'string') {
389
+ try {
390
+ json = JSON.parse(json);
391
+ } catch (e) {
392
+ return json;
393
+ }
394
+ }
395
+
396
+ // First stringify with proper indentation
397
+ let jsonString = JSON.stringify(json, null, 2);
398
+
399
+ // Escape HTML special characters EXCEPT for our span tags
400
+ jsonString = jsonString
401
+ .replace(/&/g, '&')
402
+ .replace(/</g, '&lt;')
403
+ .replace(/>/g, '&gt;');
404
+
405
+ // Now apply syntax highlighting (after escaping)
406
+ jsonString = jsonString
407
+ // Highlight keys
408
+ .replace(/"([^"]+)":/g, '"<span style="color: #2b6cb0;">$1</span>":')
409
+ // Highlight string values
410
+ .replace(/:\s*"([^"]+)"/g, ': "<span style="color: #38a169;">$1</span>"')
411
+ // Highlight numbers
412
+ .replace(/: (\d+)/g, ': <span style="color: #dd6b20;">$1</span>')
413
+ // Highlight booleans and null
414
+ .replace(/: (true|false|null)/g, ': <span style="color: #805ad5;">$1</span>');
415
+
416
+ return jsonString;
417
+ }
418
+
419
+ router.get(["/mbkauthe/info", "/mbkauthe/i"], LoginLimit, async (_, res) => {
420
+ let pkgl = {};
421
+ let latestVersion;
422
+
423
+ try {
424
+ pkgl = await getPackageLock();
425
+ latestVersion = await getLatestVersion();
426
+ //latestVersion = "Under Development"; // Placeholder for the latest version
427
+ } catch (err) {
428
+ console.error("Error fetching package-lock.json:", err);
429
+ pkgl = { error: "Failed to fetch package-lock.json" };
430
+ }
431
+
432
+ try {
433
+ res.status(200).send(`
434
+ <html>
435
+ <head>
436
+ <title>Version and Configuration Information</title>
437
+ <style>
438
+ :root {
439
+ --bg-color: #121212;
440
+ --card-bg: #1e1e1e;
441
+ --text-color: #e0e0e0;
442
+ --text-secondary: #a0a0a0;
443
+ --primary: #bb86fc;
444
+ --primary-dark: #3700b3;
445
+ --secondary: #03dac6;
446
+ --border-color: #333;
447
+ --success: #4caf50;
448
+ --warning: #ff9800;
449
+ --error: #f44336;
450
+ --key-color: #bb86fc;
451
+ --string-color: #03dac6;
452
+ --number-color: #ff7043;
453
+ --boolean-color: #7986cb;
454
+ }
455
+
456
+ body {
457
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
458
+ margin: 0;
459
+ padding: 20px;
460
+ background-color: var(--bg-color);
461
+ color: var(--text-color);
462
+ }
463
+
464
+ .container {
465
+ max-width: 1000px;
466
+ margin: 0 auto;
467
+ padding: 20px;
468
+ background: var(--card-bg);
469
+ border-radius: 8px;
470
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
471
+ }
472
+
473
+ h1 {
474
+ color: var(--primary);
475
+ text-align: center;
476
+ margin-bottom: 30px;
477
+ padding-bottom: 10px;
478
+ border-bottom: 1px solid var(--border-color);
479
+ font-weight: bold;
480
+ letter-spacing: 1px;
481
+ }
482
+
483
+ .info-section {
484
+ margin-bottom: 25px;
485
+ padding: 20px;
486
+ border: 1px solid var(--border-color);
487
+ border-radius: 8px;
488
+ background-color: rgba(30, 30, 30, 0.7);
489
+ transition: all 0.3s ease;
490
+ }
491
+
492
+ .info-section:hover {
493
+ border-color: var(--primary);
494
+ box-shadow: 0 0 0 1px var(--primary);
495
+ }
496
+
497
+ .info-section h2 {
498
+ color: var(--primary);
499
+ border-bottom: 2px solid var(--primary-dark);
500
+ padding-bottom: 8px;
501
+ margin-top: 0;
502
+ margin-bottom: 15px;
503
+ font-size: 1.2em;
504
+ display: flex;
505
+ justify-content: space-between;
506
+ align-items: center;
507
+ }
508
+
509
+ .info-row {
510
+ display: flex;
511
+ margin-bottom: 10px;
512
+ padding-bottom: 10px;
513
+ border-bottom: 1px solid var(--border-color);
514
+ }
515
+
516
+ .info-label {
517
+ font-weight: 600;
518
+ color: var(--text-secondary);
519
+ min-width: 220px;
520
+ font-size: 0.95em;
521
+ }
522
+
523
+ .info-value {
524
+ flex: 1;
525
+ word-break: break-word;
526
+ color: var(--text-color);
527
+ }
528
+
529
+ .json-container {
530
+ background: #252525;
531
+ border: 1px solid var(--border-color);
532
+ border-radius: 6px;
533
+ padding: 12px;
534
+ margin-top: 10px;
535
+ max-height: 400px;
536
+ overflow: auto;
537
+ font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
538
+ font-size: 0.85em;
539
+ white-space: pre-wrap;
540
+ position: relative;
541
+ }
542
+
543
+ .json-container pre {
544
+ margin: 0;
545
+ font-family: inherit;
546
+ }
547
+
548
+ .json-container .key {
549
+ color: var(--key-color);
550
+ }
551
+
552
+ .json-container .string {
553
+ color: var(--string-color);
554
+ }
555
+
556
+ .json-container .number {
557
+ color: var(--number-color);
558
+ }
559
+
560
+ .json-container .boolean {
561
+ color: var(--boolean-color);
562
+ }
563
+
564
+ .json-container .null {
565
+ color: var(--boolean-color);
566
+ opacity: 0.7;
567
+ }
568
+
569
+ .version-status {
570
+ display: inline-block;
571
+ padding: 3px 10px;
572
+ border-radius: 12px;
573
+ font-size: 0.8em;
574
+ font-weight: 600;
575
+ margin-left: 10px;
576
+ }
577
+
578
+ .version-up-to-date {
579
+ background: rgba(76, 175, 80, 0.2);
580
+ color: var(--success);
581
+ border: 1px solid var(--success);
582
+ }
583
+
584
+ .version-outdated {
585
+ background: rgba(244, 67, 54, 0.2);
586
+ color: var(--error);
587
+ border: 1px solid var(--error);
588
+ }
589
+
590
+ .version-fetch-error {
591
+ background: rgba(255, 152, 0, 0.2);
592
+ color: var(--warning);
593
+ border: 1px solid var(--warning);
594
+ }
595
+
596
+ .copy-btn {
597
+ background: var(--primary-dark);
598
+ color: white;
599
+ border: none;
600
+ padding: 5px 12px;
601
+ border-radius: 4px;
602
+ cursor: pointer;
603
+ font-size: 0.8em;
604
+ transition: all 0.2s ease;
605
+ display: flex;
606
+ align-items: center;
607
+ gap: 5px;
608
+ }
609
+
610
+ .copy-btn:hover {
611
+ background: var(--primary);
612
+ transform: translateY(-1px);
613
+ }
614
+
615
+ .copy-btn:active {
616
+ transform: translateY(0);
617
+ }
618
+
619
+ /* Scrollbar styling */
620
+ ::-webkit-scrollbar {
621
+ width: 8px;
622
+ height: 8px;
623
+ }
624
+
625
+ ::-webkit-scrollbar-track {
626
+ background: #2d2d2d;
627
+ border-radius: 4px;
628
+ }
629
+
630
+ ::-webkit-scrollbar-thumb {
631
+ background: #555;
632
+ border-radius: 4px;
633
+ }
634
+
635
+ ::-webkit-scrollbar-thumb:hover {
636
+ background: var(--primary);
637
+ }
638
+
639
+ /* Tooltip for copy button */
640
+ .tooltip {
641
+ position: relative;
642
+ display: inline-block;
643
+ }
644
+
645
+ .tooltip .tooltiptext {
646
+ visibility: hidden;
647
+ width: 120px;
648
+ background-color: #333;
649
+ color: #fff;
650
+ text-align: center;
651
+ border-radius: 6px;
652
+ padding: 5px;
653
+ position: absolute;
654
+ z-index: 1;
655
+ bottom: 125%;
656
+ left: 50%;
657
+ margin-left: -60px;
658
+ opacity: 0;
659
+ transition: opacity 0.3s;
660
+ font-size: 0.8em;
661
+ }
662
+
663
+ .tooltip:hover .tooltiptext {
664
+ visibility: visible;
665
+ opacity: 1;
666
+ }
667
+ </style>
668
+ <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
669
+ </head>
670
+
671
+ <body>
672
+ <div class="container">
673
+ <h1>Version and Configuration Dashboard</h1>
674
+
675
+ <div class="info-section">
676
+ <h2>Version Information</h2>
677
+ <div class="info-row">
678
+ <div class="info-label">Current Version:</div>
679
+ <div class="info-value">${packageJson.version}</div>
680
+ </div>
681
+ <div class="info-row">
682
+ <div class="info-label">Latest Version:</div>
683
+ <div class="info-value">
684
+ ${latestVersion || 'Could not fetch latest version'}
685
+ ${latestVersion ? `
686
+ <span class="version-status ${packageJson.version === latestVersion ? 'version-up-to-date' : 'version-outdated'}">
687
+ ${packageJson.version === latestVersion ? 'Up to date' : 'Update available'}
688
+ </span>
689
+ ` : `
690
+ <span class="version-status version-fetch-error">
691
+ Fetch error
692
+ </span>
693
+ `}
694
+ </div>
695
+ </div>
696
+ </div>
697
+
698
+ <div class="info-section">
699
+ <h2>Configuration Information</h2>
700
+ <div class="info-row">
701
+ <div class="info-label">APP_NAME:</div>
702
+ <div class="info-value">${mbkautheVar.APP_NAME}</div>
703
+ </div>
704
+ <div class="info-row">
705
+ <div class="info-label">MBKAUTH_TWO_FA_ENABLE:</div>
706
+ <div class="info-value">${mbkautheVar.MBKAUTH_TWO_FA_ENABLE}</div>
707
+ </div>
708
+ <div class="info-row">
709
+ <div class="info-label">COOKIE_EXPIRE_TIME:</div>
710
+ <div class="info-value">${mbkautheVar.COOKIE_EXPIRE_TIME} Days</div>
711
+ </div>
712
+ <div class="info-row">
713
+ <div class="info-label">IS_DEPLOYED:</div>
714
+ <div class="info-value">${mbkautheVar.IS_DEPLOYED}</div>
715
+ </div>
716
+ <div class="info-row">
717
+ <div class="info-label">DOMAIN:</div>
718
+ <div class="info-value">${mbkautheVar.DOMAIN}</div>
719
+ </div>
720
+ </div>
721
+
722
+ <div class="info-section">
723
+ <h2>
724
+ Package Information
725
+ <button class="copy-btn tooltip" onclick="copyToClipboard('package-json')">
726
+ <span class="tooltiptext">Copy to clipboard</span>
727
+ Copy JSON
728
+ </button>
729
+ </h2>
730
+ <div id="package-json" class="json-container"><pre>${JSON.stringify(packageJson, null, 2)}</pre></div>
731
+ </div>
732
+
733
+ <div class="info-section">
734
+ <h2>
735
+ Package Lock
736
+ <button class="copy-btn tooltip" onclick="copyToClipboard('package-lock')">
737
+ <span class="tooltiptext">Copy to clipboard</span>
738
+ Copy JSON
739
+ </button>
740
+ </h2>
741
+ <div id="package-lock" class="json-container"><pre>${JSON.stringify(pkgl, null, 2)}</pre></div>
742
+ </div>
743
+ </div>
744
+
745
+ <script>
746
+ document.addEventListener('DOMContentLoaded', function() {
747
+ // Apply syntax highlighting to all JSON containers
748
+ const jsonContainers = document.querySelectorAll('.json-container pre');
749
+ jsonContainers.forEach(container => {
750
+ container.innerHTML = syntaxHighlight(container.textContent);
751
+ });
752
+ });
753
+
754
+ function syntaxHighlight(json) {
755
+ if (typeof json !== 'string') {
756
+ json = JSON.stringify(json, null, 2);
757
+ }
758
+
759
+ // Escape HTML
760
+ json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
761
+
762
+ // Apply syntax highlighting
763
+ return json.replace(
764
+ /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
765
+ function(match) {
766
+ let cls = 'number';
767
+ if (/^"/.test(match)) {
768
+ if (/:$/.test(match)) {
769
+ cls = 'key';
770
+ } else {
771
+ cls = 'string';
772
+ }
773
+ } else if (/true|false/.test(match)) {
774
+ cls = 'boolean';
775
+ } else if (/null/.test(match)) {
776
+ cls = 'null';
777
+ }
778
+ return '<span class="' + cls + '">' + match + '</span>';
779
+ }
780
+ );
781
+ }
782
+
783
+ function copyToClipboard(elementId) {
784
+ const element = document.getElementById(elementId);
785
+ const text = element.textContent;
786
+ navigator.clipboard.writeText(text).then(() => {
787
+ const btn = element.parentElement.querySelector('.copy-btn');
788
+ const originalText = btn.innerHTML;
789
+ btn.innerHTML = '<span class="tooltiptext">Copied!</span>✓ Copied';
790
+ setTimeout(() => {
791
+ btn.innerHTML = '<span class="tooltiptext">Copy to clipboard</span>' + originalText.replace('✓ Copied', 'Copy JSON');
792
+ }, 2000);
793
+ }).catch(err => {
794
+ console.error('Failed to copy text: ', err);
795
+ });
796
+ }
797
+ </script>
798
+ </body>
799
+ </html>
800
+ `);
801
+ } catch (err) {
802
+ console.error("Error fetching version information:", err);
803
+ res.status(500).send(`
804
+ <html>
805
+ <head>
806
+ <title>Error</title>
807
+ </head>
808
+ <body>
809
+ <h1>Error</h1>
810
+ <p>Failed to fetch version information. Please try again later.</p>
811
+ </body>
812
+ </html>
813
+ `);
814
+ }
815
+ });
816
+
817
+ export { getLatestVersion };
340
818
  export default router;
package/lib/pool.js CHANGED
@@ -13,28 +13,18 @@ try {
13
13
  if (!mbkautheVar) {
14
14
  throw new Error("mbkautheVar is not defined");
15
15
  }
16
- const requiredKeys = ["APP_NAME", "RECAPTCHA_Enabled", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
16
+ const requiredKeys = ["APP_NAME", "SESSION_SECRET_KEY", "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "DOMAIN"];
17
17
  requiredKeys.forEach(key => {
18
18
  if (!mbkautheVar[key]) {
19
19
  throw new Error(`mbkautheVar.${key} is required`);
20
20
  }
21
21
  });
22
- if (mbkautheVar.RECAPTCHA_Enabled === "true") {
23
- if (mbkautheVar.RECAPTCHA_SECRET_KEY === undefined) {
24
- throw new Error("mbkautheVar.RECAPTCHA_SECRET_KEY is required");
25
- }
26
- }
27
22
  if (mbkautheVar.COOKIE_EXPIRE_TIME !== undefined) {
28
23
  const expireTime = parseFloat(mbkautheVar.COOKIE_EXPIRE_TIME);
29
24
  if (isNaN(expireTime) || expireTime <= 0) {
30
25
  throw new Error("mbkautheVar.COOKIE_EXPIRE_TIME must be a valid positive number");
31
26
  }
32
27
  }
33
- if (mbkautheVar.BypassUsers !== undefined) {
34
- if (!Array.isArray(mbkautheVar.BypassUsers)) {
35
- throw new Error("mbkautheVar.BypassUsers must be a valid array");
36
- }
37
- }
38
28
 
39
29
  const poolConfig = {
40
30
  connectionString: mbkautheVar.LOGIN_DB,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mbkauthe",
3
- "version": "1.1.12",
3
+ "version": "1.1.14",
4
4
  "description": "MBKTechStudio's reusable authentication system for Node.js applications.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -5,7 +5,8 @@
5
5
  <head>
6
6
  <meta charset="UTF-8">
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
- <meta name="description" content="Log in to portal.mbktechstudio.com to access your resources and manage projects securely.">
8
+ <meta name="description"
9
+ content="Log in to portal.mbktechstudio.com to access your resources and manage projects securely.">
9
10
  <meta name="keywords" content="MBK Tech Studio, Web-Portal, Web, Portal, Admin-Panel, Admin, login">
10
11
  <meta property="og:title" content="Login | MBK Tech Studio" />
11
12
  <meta property="og:image" content="https://www.mbktechstudio.com/Assets/Images/Icon/logo.png" />
@@ -15,8 +16,8 @@
15
16
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
16
17
  <link rel="preconnect" href="https://fonts.googleapis.com">
17
18
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
18
- <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
19
- <script src="https://www.google.com/recaptcha/api.js" async defer></script>
19
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
20
+ rel="stylesheet">
20
21
  <style>
21
22
  :root {
22
23
  --primary: #4361ee;
@@ -270,12 +271,6 @@
270
271
  font-weight: 500;
271
272
  }
272
273
 
273
- .recaptcha-container {
274
- margin: 1rem 0;
275
- display: flex;
276
- justify-content: center;
277
- }
278
-
279
274
  .token-container {
280
275
  animation: fadeInUp 0.4s ease-out;
281
276
  }
@@ -418,7 +413,7 @@
418
413
  .remember-me label:hover {
419
414
  color: var(--light);
420
415
  }
421
-
416
+
422
417
  .WarningboxInfo {
423
418
  background: var(--dark-light);
424
419
  border: 0.5px solid var(--warning);
@@ -483,11 +478,6 @@
483
478
  <i class="fas fa-info-circle input-icon" onclick="tokeninfo()"></i>
484
479
  </div>
485
480
 
486
- <div class="recaptcha-container">
487
- <div class="g-recaptcha" data-theme="dark" data-sitekey="6LfhaPgqAAAAAPgOw7r3rNOHKKfh5d7K3MMJeUHo">
488
- </div>
489
- </div>
490
-
491
481
  <div class="form-group remember-me">
492
482
  <input type="checkbox" id="rememberMe" name="rememberMe">
493
483
  <label for="rememberMe">Remember me</label>
@@ -553,7 +543,6 @@
553
543
  const username = document.getElementById('loginUsername').value.trim();
554
544
  const password = document.getElementById('loginPassword').value.trim();
555
545
  const token = document.getElementById('token') ? document.getElementById('token').value.trim() : '';
556
- const recaptchaResponse = grecaptcha.getResponse();
557
546
  const loginButton = document.getElementById('loginButton');
558
547
  const loginButtonText = document.getElementById('loginButtonText');
559
548
  const rememberMe = document.getElementById('rememberMe').checked;
@@ -575,8 +564,7 @@
575
564
  body: JSON.stringify({
576
565
  username,
577
566
  password,
578
- token,
579
- recaptcha: recaptchaResponse
567
+ token
580
568
  })
581
569
  })
582
570
  .then(response => response.json())
@@ -590,7 +578,7 @@
590
578
  } else {
591
579
  localStorage.removeItem('rememberedUsername');
592
580
  }
593
-
581
+
594
582
  // Redirect to the appropriate page
595
583
  const redirectUrl = new URLSearchParams(window.location.search).get('redirect');
596
584
  window.location.href = redirectUrl ? decodeURIComponent(redirectUrl) : '{{customURL}}';
@@ -599,7 +587,6 @@
599
587
  loginButtonText.textContent = 'Login';
600
588
  } else {
601
589
  // Handle errors
602
- grecaptcha.reset();
603
590
  loginButton.disabled = false;
604
591
  loginButtonText.textContent = 'Login';
605
592
 
@@ -615,7 +602,6 @@
615
602
  }
616
603
  })
617
604
  .catch(error => {
618
- grecaptcha.reset();
619
605
  loginButton.disabled = false;
620
606
  loginButtonText.textContent = 'Login';
621
607
  console.error('Error:', error);