From b9050139507a139c5b147abe5ce833a9dbe2b963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 28 Nov 2023 20:58:07 -0500 Subject: [PATCH] fix: closes #12185, fix cli user password reset refactor session get/destroy --- src/api/users.js | 7 +------ src/cli/user.js | 1 + src/database/index.js | 22 ++++++++++++++++++++++ src/socket.io/index.js | 8 ++------ src/user/auth.js | 18 +++++------------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/api/users.js b/src/api/users.js index ea0ce2f6b2..eda2b15d62 100644 --- a/src/api/users.js +++ b/src/api/users.js @@ -1,6 +1,5 @@ 'use strict'; -const util = require('util'); const path = require('path'); const fs = require('fs').promises; @@ -345,10 +344,6 @@ usersAPI.deleteToken = async (caller, { uid, token }) => { return true; }; -const getSessionAsync = util.promisify((sid, callback) => { - db.sessionStore.get(sid, (err, sessionObj) => callback(err, sessionObj || null)); -}); - usersAPI.revokeSession = async (caller, { uid, uuid }) => { // Only admins or global mods (besides the user themselves) can revoke sessions if (parseInt(uid, 10) !== caller.uid && !await user.isAdminOrGlobalMod(caller.uid)) { @@ -359,7 +354,7 @@ usersAPI.revokeSession = async (caller, { uid, uuid }) => { let _id; for (const sid of sids) { /* eslint-disable no-await-in-loop */ - const sessionObj = await getSessionAsync(sid); + const sessionObj = await db.sessionStoreGet(sid); if (sessionObj && sessionObj.meta && sessionObj.meta.uuid === uuid) { _id = sid; break; diff --git a/src/cli/user.js b/src/cli/user.js index bbd747865f..f2db7e4a58 100644 --- a/src/cli/user.js +++ b/src/cli/user.js @@ -77,6 +77,7 @@ let winston; async function init() { db = require('../database'); await db.init(); + await db.initSessionStore(); user = require('../user'); groups = require('../groups'); diff --git a/src/database/index.js b/src/database/index.js index 51febea19d..2366ae3671 100644 --- a/src/database/index.js +++ b/src/database/index.js @@ -34,4 +34,26 @@ primaryDB.initSessionStore = async function () { primaryDB.sessionStore = await sessionStoreDB.createSessionStore(sessionStoreConfig); }; +function promisifySessionStoreMethod(method, sid) { + return new Promise((resolve, reject) => { + if (!primaryDB.sessionStore) { + resolve(method === 'get' ? null : undefined); + return; + } + + primaryDB.sessionStore[method](sid, (err, result) => { + if (err) reject(err); + else resolve(method === 'get' ? result || null : undefined); + }); + }); +} + +primaryDB.sessionStoreGet = function (sid) { + return promisifySessionStoreMethod('get', sid); +}; + +primaryDB.sessionStoreDestroy = function (sid) { + return promisifySessionStoreMethod('destroy', sid); +}; + module.exports = primaryDB; diff --git a/src/socket.io/index.js b/src/socket.io/index.js index c10f271585..d0ba0b4b19 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -241,10 +241,6 @@ async function checkMaintenance(socket) { throw new Error(`[[pages:maintenance.text, ${validator.escape(String(meta.config.title || 'NodeBB'))}]]`); } -const getSessionAsync = util.promisify( - (sid, callback) => db.sessionStore.get(sid, (err, sessionObj) => callback(err, sessionObj || null)) -); - async function validateSession(socket, errorMsg) { const req = socket.request; const { sessionId } = await plugins.hooks.fire('filter:sockets.sessionId', { @@ -256,7 +252,7 @@ async function validateSession(socket, errorMsg) { return; } - const sessionData = await getSessionAsync(sessionId); + const sessionData = await db.sessionStoreGet(sessionId); if (!sessionData) { throw new Error(errorMsg); } @@ -282,7 +278,7 @@ async function authorize(request, callback) { request: request, }); - const sessionData = await getSessionAsync(sessionId); + const sessionData = await db.sessionStoreGet(sessionId); request.session = sessionData; let uid = 0; if (sessionData && sessionData.passport && sessionData.passport.user) { diff --git a/src/user/auth.js b/src/user/auth.js index 5330903a15..954d00a0c5 100644 --- a/src/user/auth.js +++ b/src/user/auth.js @@ -2,7 +2,6 @@ const winston = require('winston'); const validator = require('validator'); -const util = require('util'); const _ = require('lodash'); const db = require('../database'); const meta = require('../meta'); @@ -62,17 +61,10 @@ module.exports = function (User) { ]); }; - const getSessionFromStore = util.promisify( - (sid, callback) => db.sessionStore.get(sid, (err, sessObj) => callback(err, sessObj || null)) - ); - const sessionStoreDestroy = util.promisify( - (sid, callback) => db.sessionStore.destroy(sid, err => callback(err)) - ); - User.auth.getSessions = async function (uid, curSessionId) { await cleanExpiredSessions(uid); const sids = await db.getSortedSetRevRange(`uid:${uid}:sessions`, 0, 19); - let sessions = await Promise.all(sids.map(sid => getSessionFromStore(sid))); + let sessions = await Promise.all(sids.map(sid => db.sessionStoreGet(sid))); sessions = sessions.map((sessObj, idx) => { if (sessObj && sessObj.meta) { sessObj.meta.current = curSessionId === sids[idx]; @@ -93,7 +85,7 @@ module.exports = function (User) { const expiredSids = []; await Promise.all(Object.keys(uuidMapping).map(async (uuid) => { const sid = uuidMapping[uuid]; - const sessionObj = await getSessionFromStore(sid); + const sessionObj = await db.sessionStoreGet(sid); const expired = !sessionObj || !sessionObj.hasOwnProperty('passport') || !sessionObj.passport.hasOwnProperty('user') || parseInt(sessionObj.passport.user, 10) !== parseInt(uid, 10); @@ -128,13 +120,13 @@ module.exports = function (User) { User.auth.revokeSession = async function (sessionId, uid) { winston.verbose(`[user.auth] Revoking session ${sessionId} for user ${uid}`); - const sessionObj = await getSessionFromStore(sessionId); + const sessionObj = await db.sessionStoreGet(sessionId); if (sessionObj && sessionObj.meta && sessionObj.meta.uuid) { await db.deleteObjectField(`uid:${uid}:sessionUUID:sessionId`, sessionObj.meta.uuid); } await Promise.all([ db.sortedSetRemove(`uid:${uid}:sessions`, sessionId), - sessionStoreDestroy(sessionId), + db.sessionStoreDestroy(sessionId), ]); }; @@ -159,7 +151,7 @@ module.exports = function (User) { await Promise.all([ db.deleteAll(sessionKeys.concat(sessionUUIDKeys)), - ...sids.map(sid => sessionStoreDestroy(sid)), + ...sids.map(sid => db.sessionStoreDestroy(sid)), ]); }, { batch: 1000 }); };