From 4c33f4e60eb2bc4d6473231f2f63edbf0cf99828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Bazureau?= Date: Mon, 8 Nov 2021 14:25:22 +0100 Subject: [PATCH] fix proxy pass parsing on some keys #393 --- lib/routes/apiv1.js | 14 +++++++------- lib/util.js | 12 ++++++++++++ web/static/scripts/redisCommander.js | 20 ++++++++++++-------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/lib/routes/apiv1.js b/lib/routes/apiv1.js index 4e95b2ee..e5dcc523 100644 --- a/lib/routes/apiv1.js +++ b/lib/routes/apiv1.js @@ -328,7 +328,7 @@ function getRedisCommands(req, res) { function getKeyDetails (req, res, next) { - let key = req.params.key; + let key = myutil.decodeKey(req.params.key); let redisConnection = res.locals.connection; console.log(`loading key "${key}" from "${res.locals.connectionId}"`); redisConnection.type(key, function (err, type) { @@ -811,7 +811,7 @@ function postDeleteXSetMember (req, res, next) { // hash function getHashField (req, res, next) { - let key = req.params.key; + let key = myutil.decodeKey(req.params.key); let field = req.query.field; if (!field) { console.error('Missing "field" query parameter'); @@ -1097,7 +1097,7 @@ function postKey (req, res, next) { } function saveKey (req, res, next) { - let key = req.params.key; + let key = myutil.decodeKey(req.params.key); let redisConnection = res.locals.connection; console.log(`saving key "${key}"`); @@ -1137,7 +1137,7 @@ function saveKey (req, res, next) { } function decodeKey (req, res, next) { - let key = req.params.key; + let key = myutil.decodeKey(req.params.key); let redisConnection = res.locals.connection; redisConnection.get(key, function (err, val) { @@ -1176,7 +1176,7 @@ function encodeString (req, res, next) { } function deleteKey (req, res, next) { - let key = req.params.key; + let key = myutil.decodeKey(req.params.key); let redisConnection = res.locals.connection; console.log(`deleting key "${key}"`); redisConnection.del(key, function (err) { @@ -1190,7 +1190,7 @@ function deleteKey (req, res, next) { } function renameKey (req, res, next) { - const keyOld = req.params.key; + const keyOld = rmyutil.decodeKey(req.params.key); const keyNew = req.body.key; const force = req.body.force; const redisConnection = res.locals.connection; @@ -1402,7 +1402,7 @@ function getKeysTree (req, res, next) { function postKeys (req, res, next) { if (req.query.action === 'delete') { - deleteKeys(req.params.key, res, next); + deleteKeys(myutil.decodeKey(req.params.key), res, next); } else { next(new Error("Invalid action '" + req.query.action + "'")); } diff --git a/lib/util.js b/lib/util.js index 3f492ea8..9fcb9e0c 100644 --- a/lib/util.js +++ b/lib/util.js @@ -126,6 +126,17 @@ function addElement(newElem, callback) { return callback(this); } +// Decode key +function decodeKey(encodedKey) { + return Buffer.from( + encodedKey + .replace(/-/g, '+') + .replace(/_/g, '/') + .replace(/\./g, '='), + 'base64', + ).toString(); +} + // Config Util functions - used for old config file inside home dir // ========== @@ -828,6 +839,7 @@ exports.distinct = distinct; exports.decodeHTMLEntities = decodeHTMLEntities; exports.encodeHTMLEntities = encodeHTMLEntities; exports.addElement = addElement; +exports.decodeKey = decodeKey; exports.createRedisClient = createRedisClient; diff --git a/web/static/scripts/redisCommander.js b/web/static/scripts/redisCommander.js index 8bffbfc3..53d24803 100644 --- a/web/static/scripts/redisCommander.js +++ b/web/static/scripts/redisCommander.js @@ -251,13 +251,17 @@ function getRootConnection (node) { return node.parents[node.parents.length-2]; } +function encodeKey(key) { + return encodeURIComponent(window.btoa(key).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '.')); +} + function loadKey (connectionId, key, index) { if (index) { - $.get('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(key) + '?index=' + index) + $.get('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeKey(key) + '?index=' + index) .done(processData) .fail(errorHandler); } else { - $.get('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(key)) + $.get('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeKey(key)) .done(processData) .fail(errorHandler) } @@ -467,7 +471,7 @@ function addNewKey() { var newKeyModal = $('#addKeyModal'); var newKey = newKeyModal.find('#keyValue').val(); var connectionId = newKeyModal.find('#addKeyConnectionId').val(); - var action = 'apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(newKey); + var action = 'apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeKey(newKey); console.log('saving new key ' + newKey); newKeyModal.find('#saveKeyButton').attr('disabled', 'disabled').html(' Saving'); @@ -495,7 +499,7 @@ function renameExistingKey() { var oldKey = modal.find('#currentKeyName').val(); var newKey = modal.find('#renamedKeyName').val(); var connectionId = modal.find('#renameKeyConnectionId').val(); - var action = 'apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(oldKey); + var action = 'apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeKey(oldKey); console.log('renaming ' + oldKey + ' to new key ' + newKey); modal.find('#renameKeyButton').attr('disabled', 'disabled').html(' Saving'); @@ -726,7 +730,7 @@ function deleteKey (connectionId, key) { // delete this specific key only, no wildcard here var result = confirm('Are you sure you want to delete "' + key + '" from "' + node.text + '"?'); if (result) { - $.post('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(key) + '?action=delete', function (data, status) { + $.post('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeKey(key) + '?action=delete', function (data, status) { if (status !== 'success') { return alert('Could not delete key'); } @@ -746,7 +750,7 @@ function decodeKey (connectionId, key) { connectionId = getRootConnection(node); } - $.post('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(key) + '?action=decode', function (data, status) { + $.post('apiv2/key/' + encodeURIComponent(connectionId) + '/' + encodeKey(key) + '?action=decode', function (data, status) { if (status !== 'success') { return alert('Could not decode key'); } @@ -783,7 +787,7 @@ function deleteBranch (connectionId, branchPrefix) { var query = (branchPrefix.endsWith(foldingCharacter) ? branchPrefix : branchPrefix + foldingCharacter) + '*'; var result = confirm('Are you sure you want to delete "' + query + '" from "' + node.text + '"? This will delete all children as well!'); if (result) { - $.post('apiv2/keys/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(query) + '?action=delete', function (data, status) { + $.post('apiv2/keys/' + encodeURIComponent(connectionId) + '/' + encodeKey(query) + '?action=delete', function (data, status) { if (status !== 'success') { return alert('Could not delete branch'); } @@ -875,7 +879,7 @@ function editHashField (connectionId, key, field, value) { } function showHashField (connectionId, key, field) { - $.get('apiv2/hash/key/' + encodeURIComponent(connectionId) + '/' + encodeURIComponent(key) + '?field=' + encodeURIComponent(field)) + $.get('apiv2/hash/key/' + encodeURIComponent(connectionId) + '/' + encodeKey(key) + '?field=' + encodeURIComponent(field)) .done(processData) .fail(errorHandler)