mbkauthe 4.7.1 → 4.8.0

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.
@@ -1,11 +1,14 @@
1
1
  import express from "express";
2
2
  import { renderError } from "#response.js";
3
3
  import { dblogin } from "#pool.js";
4
+ import { getQueryCount, getQueryLog, resetQueryCount, resetQueryLog } from "../utils/dbQueryLogger.js";
4
5
  import { mbkautheVar } from "#config.js";
5
6
  import rateLimit from 'express-rate-limit';
6
7
 
7
8
  const router = express.Router();
8
9
 
10
+ const isDbLogsEnabled = () => process.env.env === "dev" && process.env.dbLogs === "true";
11
+
9
12
  // Rate limiter for info/test routes
10
13
  const LogLimit = rateLimit({
11
14
  windowMs: 1 * 60 * 1000,
@@ -23,33 +26,68 @@ const LogLimit = rateLimit({
23
26
  // DB stats API (JSON)
24
27
  router.get(["/db.json"], LogLimit, async (req, res) => {
25
28
  try {
26
- const queryCount = typeof dblogin.getQueryCount === 'function' ? dblogin.getQueryCount() : null;
29
+ const isDev = isDbLogsEnabled();
27
30
  const queryLimit = Number(req.query.limit) || 50;
28
- const queryLog = typeof dblogin.getQueryLog === 'function' ? dblogin.getQueryLog({ limit: queryLimit }) : [];
29
- const resetRequested = req.query.reset === '1';
30
31
 
31
- if (resetRequested) {
32
- if (typeof dblogin.resetQueryCount === 'function') dblogin.resetQueryCount();
33
- if (typeof dblogin.resetQueryLog === 'function') dblogin.resetQueryLog();
32
+ if (!isDev) {
33
+ return res.status(403).json({
34
+ success: false,
35
+ message: "DB logs are disabled.",
36
+ isDev,
37
+ queryCount: 0,
38
+ queryLimit,
39
+ queryLog: []
40
+ });
34
41
  }
35
42
 
36
- return res.json({ queryCount, queryLimit, queryLog, resetDone: resetRequested });
43
+ const queryCount = typeof getQueryCount === 'function' ? getQueryCount() : (typeof dblogin.getQueryCount === 'function' ? dblogin.getQueryCount() : 0);
44
+ const queryLog = typeof getQueryLog === 'function' ? getQueryLog({ limit: queryLimit }) : (typeof dblogin.getQueryLog === 'function' ? dblogin.getQueryLog({ limit: queryLimit }) : []);
45
+
46
+ return res.json({ queryCount, queryLimit, queryLog, isDev });
37
47
  } catch (err) {
38
48
  console.error('[mbkauthe] /db.json route error:', err);
39
49
  return res.status(500).json({ success: false, message: 'Could not fetch DB stats.' });
40
50
  }
41
51
  });
42
52
 
53
+ // Dedicated reset API for DB logs and counters
54
+ router.post(["/db/reset"], LogLimit, async (req, res) => {
55
+ try {
56
+ const isDev = isDbLogsEnabled();
57
+ if (!isDev) {
58
+ return res.status(403).json({
59
+ success: false,
60
+ message: "DB logs are disabled.",
61
+ isDev
62
+ });
63
+ }
64
+
65
+ if (typeof resetQueryCount === 'function') resetQueryCount();
66
+ else if (typeof dblogin.resetQueryCount === 'function') dblogin.resetQueryCount();
67
+
68
+ if (typeof resetQueryLog === 'function') resetQueryLog();
69
+ else if (typeof dblogin.resetQueryLog === 'function') dblogin.resetQueryLog();
70
+
71
+ return res.json({ success: true, message: 'Query log and count have been reset.' });
72
+ } catch (err) {
73
+ console.error('[mbkauthe] /db/reset route error:', err);
74
+ return res.status(500).json({ success: false, message: 'Could not reset DB stats.' });
75
+ }
76
+ });
77
+
43
78
  // DB stats page (HTML)
44
79
  router.get(["/db"], LogLimit, async (req, res) => {
45
80
  try {
81
+ const isDev = isDbLogsEnabled();
46
82
  const queryLimit = Number(req.query.limit) || 50;
47
83
  const resetDone = req.query.resetDone === '1';
48
84
  return res.render('pages/dbLogs.handlebars', {
49
85
  layout: false,
50
86
  appName: mbkautheVar.APP_NAME,
51
87
  queryLimit,
52
- resetDone
88
+ resetDone,
89
+ isDev,
90
+ disabledMessage: isDev ? null : 'DB logs are disabled.'
53
91
  });
54
92
  } catch (err) {
55
93
  console.error('[mbkauthe] /db route error:', err);
@@ -6,7 +6,7 @@ import { renderError, renderPage } from "#response.js";
6
6
  import { authenticate, validateSession, validateSessionAndRole } from "../middleware/auth.js";
7
7
  import { ErrorCodes, ErrorMessages, createErrorResponse } from "../utils/errors.js";
8
8
  import { dblogin } from "#pool.js";
9
- import { clearSessionCookies, decryptSessionId } from "#cookies.js";
9
+ import { clearSessionCookies, decryptSessionId, cachedCookieOptions } from "#cookies.js";
10
10
  import { fileURLToPath } from "url";
11
11
  import path from "path";
12
12
  import fs from "fs";
@@ -91,8 +91,12 @@ router.get('/user/profilepic', async (req, res) => {
91
91
  }
92
92
 
93
93
  const username = req.session.user.username;
94
- const cacheKey = `profilepic_${username}`;
95
- let imageUrl = req.session[cacheKey];
94
+ let imageUrl = null;
95
+ const cookieUser = req.cookies?.profileImageUser;
96
+ const cookieImageUrl = req.cookies?.profileImageUrl;
97
+ if (cookieUser === username && typeof cookieImageUrl === 'string' && cookieImageUrl.length > 0) {
98
+ imageUrl = cookieImageUrl;
99
+ }
96
100
 
97
101
  // If not in cache, fetch from DB
98
102
  if (!imageUrl) {
@@ -107,7 +111,8 @@ router.get('/user/profilepic', async (req, res) => {
107
111
  } else {
108
112
  imageUrl = 'default';
109
113
  }
110
- req.session[cacheKey] = imageUrl;
114
+ res.cookie('profileImageUrl', imageUrl, { ...cachedCookieOptions, httpOnly: false });
115
+ res.cookie('profileImageUser', username, { ...cachedCookieOptions, httpOnly: false });
111
116
  }
112
117
 
113
118
  // Generate ETag based on username and image URL
@@ -137,7 +142,8 @@ router.get('/user/profilepic', async (req, res) => {
137
142
 
138
143
  if (!imageResponse.ok) {
139
144
  console.warn(`[mbkauthe] Failed to fetch profile pic from ${imageUrl}, status: ${imageResponse.status}`);
140
- req.session[cacheKey] = 'default';
145
+ res.cookie('profileImageUrl', 'default', { ...cachedCookieOptions, httpOnly: false });
146
+ res.cookie('profileImageUser', username, { ...cachedCookieOptions, httpOnly: false });
141
147
  return serveDefaultIcon();
142
148
  }
143
149
 
@@ -147,7 +153,8 @@ router.get('/user/profilepic', async (req, res) => {
147
153
  imageResponse.body.pipe(res);
148
154
  } catch (fetchErr) {
149
155
  console.error('[mbkauthe] Error fetching external profile picture:', fetchErr);
150
- req.session[cacheKey] = 'default';
156
+ res.cookie('profileImageUrl', 'default', { ...cachedCookieOptions, httpOnly: false });
157
+ res.cookie('profileImageUser', username, { ...cachedCookieOptions, httpOnly: false });
151
158
  return serveDefaultIcon();
152
159
  }
153
160
 
@@ -503,8 +510,7 @@ router.get(["/info", "/i"], LoginLimit, async (req, res) => {
503
510
  }
504
511
 
505
512
  try {
506
- res.render("pages/info_mbkauthe.handlebars", {
507
- layout: false,
513
+ renderPage(req, res, "pages/info_mbkauthe.handlebars", false, {
508
514
  mbkautheVar: safe_mbkautheVar,
509
515
  CurrentVersion: packageJson.version,
510
516
  APP_VERSION: appVersion,