This is an automated email from the ASF dual-hosted git repository. glynnbird pushed a commit to branch fix-basicauth-percent-encoding in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git
commit eb82c2601d8572903f5c96bdecfeb0f33119c8f5 Author: Glynn Bird <[email protected]> AuthorDate: Fri Feb 6 10:22:43 2026 +0000 ensure that username and password returned from new URL are decoded before use --- lib/nano.js | 2 +- test/nano.basicauth.test.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/nano.js b/lib/nano.js index f21389a..ad5dfda 100644 --- a/lib/nano.js +++ b/lib/nano.js @@ -56,7 +56,7 @@ module.exports = exports = function dbScope (cfg) { cfg.plainURL = `${cfg.parsedURL.origin}${cfg.parsedURL.pathname}` cfg.headers = cfg.headers || {} if (cfg.parsedURL.username && cfg.parsedURL.password) { - cfg.headers.Authorization = 'Basic ' + Buffer.from(`${cfg.parsedURL.username}:${cfg.parsedURL.password}`).toString('base64') + cfg.headers.Authorization = 'Basic ' + Buffer.from(`${decodeURIComponent(cfg.parsedURL.username)}:${decodeURIComponent(cfg.parsedURL.password)}`).toString('base64') } // look for agentOptions diff --git a/test/nano.basicauth.test.js b/test/nano.basicauth.test.js new file mode 100644 index 0000000..30a3b9d --- /dev/null +++ b/test/nano.basicauth.test.js @@ -0,0 +1,36 @@ +// Licensed under the Apache License, Version 2.0 (the 'License'); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +const test = require('node:test') +const assert = require('node:assert/strict') +const COUCH_URL="http://admin[:admin]@localhost:5984" +const { mockAgent, mockPool, JSON_HEADERS } = require('./mock.js') +const Nano = require('..') +const nano = Nano(COUCH_URL) + +test('should handle special characters in username & password', async () => { + // mocks + const auth = 'Basic ' + Buffer.from('admin[:admin]').toString('base64') + mockPool + .intercept({ + path: '/_all_dbs', + headers: { + 'Authorization': auth + } + }) + .reply(200, ['a'], JSON_HEADERS) + + // test POST /_session + const q = await nano.db.list() + assert.deepEqual(q, ['a']) + mockAgent.assertNoPendingInterceptors() +})
