This is an automated email from the ASF dual-hosted git repository.

glynnbird pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git


The following commit(s) were added to refs/heads/main by this push:
     new c757679  Fix basicauth for credentials requiring percent encoding 
(#364)
c757679 is described below

commit c757679a1627b224f2bb338ba1ad1ea0efd616a3
Author: Glynn Bird <[email protected]>
AuthorDate: Fri Feb 6 12:47:54 2026 +0000

    Fix basicauth for credentials requiring percent encoding (#364)
    
    * ensure that username and password returned from new URL are decoded 
before use
    
    * tests working
    
    * added node 24 to the testing matrix
    
    * 11.0.4 + dependency bump
    
    ---------
    
    Co-authored-by: Glynn Bird <[email protected]>
---
 .github/workflows/ci.yaml   |  2 +-
 lib/nano.js                 |  2 +-
 package-lock.json           | 36 ++++++++++++++++++------------------
 package.json                |  8 ++++----
 test/nano.basicauth.test.js | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 62 insertions(+), 24 deletions(-)

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 6584615..221d04f 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -22,7 +22,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [20.x, 22.x]
+        node-version: [20.x, 22.x, 24.x]
 
     steps:
       - uses: actions/checkout@v3
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/package-lock.json b/package-lock.json
index 7987105..d5fbaac 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,36 +1,36 @@
 {
   "name": "nano",
-  "version": "11.0.3",
+  "version": "11.0.4",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "nano",
-      "version": "11.0.3",
+      "version": "11.0.4",
       "license": "Apache-2.0",
       "devDependencies": {
-        "@types/node": "^24.4.0",
-        "typescript": "^5.9.2",
-        "undici": "^7.16.0"
+        "@types/node": "^25.2.1",
+        "typescript": "^5.9.3",
+        "undici": "^7.20.0"
       },
       "engines": {
         "node": ">=20.0"
       }
     },
     "node_modules/@types/node": {
-      "version": "24.4.0",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-24.4.0.tgz";,
-      "integrity": 
"sha512-gUuVEAK4/u6F9wRLznPUU4WGUacSEBDPoC2TrBkw3GAnOLHBL45QdfHOXp1kJ4ypBGLxTOB+t7NJLpKoC3gznQ==",
+      "version": "25.2.1",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz";,
+      "integrity": 
"sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "undici-types": "~7.11.0"
+        "undici-types": "~7.16.0"
       }
     },
     "node_modules/typescript": {
-      "version": "5.9.2",
-      "resolved": 
"https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz";,
-      "integrity": 
"sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
+      "version": "5.9.3",
+      "resolved": 
"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz";,
+      "integrity": 
"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
       "dev": true,
       "license": "Apache-2.0",
       "bin": {
@@ -42,9 +42,9 @@
       }
     },
     "node_modules/undici": {
-      "version": "7.16.0",
-      "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz";,
-      "integrity": 
"sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==",
+      "version": "7.20.0",
+      "resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz";,
+      "integrity": 
"sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -52,9 +52,9 @@
       }
     },
     "node_modules/undici-types": {
-      "version": "7.11.0",
-      "resolved": 
"https://registry.npmjs.org/undici-types/-/undici-types-7.11.0.tgz";,
-      "integrity": 
"sha512-kt1ZriHTi7MU+Z/r9DOdAI3ONdaR3M3csEaRc6ewa4f4dTvX4cQCbJ4NkEn0ohE4hHtq85+PhPSTY+pO/1PwgA==",
+      "version": "7.16.0",
+      "resolved": 
"https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz";,
+      "integrity": 
"sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
       "dev": true,
       "license": "MIT"
     }
diff --git a/package.json b/package.json
index 483d1f8..6048c3e 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "license": "Apache-2.0",
   "homepage": "http://github.com/apache/couchdb-nano";,
   "repository": "http://github.com/apache/couchdb-nano";,
-  "version": "11.0.3",
+  "version": "11.0.4",
   "author": "Apache CouchDB <[email protected]> 
(http://couchdb.apache.org)",
   "keywords": [
     "couchdb",
@@ -19,9 +19,9 @@
   "dependencies": {
   },
   "devDependencies": {
-    "undici": "^7.16.0",
-    "@types/node": "^24.4.0",
-    "typescript": "^5.9.2"
+    "undici": "^7.20.0",
+    "@types/node": "^25.2.1",
+    "typescript": "^5.9.3"
   },
   "scripts": {
     "test": "tsc lib/nano.d.ts && node --test ./test/*.test.js"
diff --git a/test/nano.basicauth.test.js b/test/nano.basicauth.test.js
new file mode 100644
index 0000000..1031f35
--- /dev/null
+++ b/test/nano.basicauth.test.js
@@ -0,0 +1,38 @@
+// 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]@127.0.0.1:5984";
+const { mockAgent, mockPool, JSON_HEADERS } = require('./mock.js')
+const Nano = require('..')
+const nano = Nano({ url: COUCH_URL })
+const pkg = require('../package.json')
+
+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,
+        'content-type': 'application/json'
+      }
+    })
+    .reply(200, ['a'], JSON_HEADERS)
+
+  // test POST /_session
+  const q = await nano.db.list()
+  assert.deepEqual(q, ['a'])
+  mockAgent.assertNoPendingInterceptors()
+})

Reply via email to