From 6204e90e9cd96eaf41e72977bdda7172b828cb7d Mon Sep 17 00:00:00 2001 From: Philipp Kolmann Date: Thu, 21 Aug 2025 10:11:56 +0200 Subject: [PATCH 1/3] fix(digest-auth): fix Digest Auth when no QOP is set (working on usebruno/bruno#5378) --- .../src/auth/digestauth-helper.js | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/bruno-requests/src/auth/digestauth-helper.js b/packages/bruno-requests/src/auth/digestauth-helper.js index d6b93b98f..4499555a7 100644 --- a/packages/bruno-requests/src/auth/digestauth-helper.js +++ b/packages/bruno-requests/src/auth/digestauth-helper.js @@ -99,22 +99,36 @@ export function addDigestInterceptor(axiosInstance, request) { const method = (originalRequest.method || request.method || 'GET').toUpperCase(); const HA1 = md5(`${username}:${authDetails.realm}:${password}`); const HA2 = md5(`${method}:${uri}`); - const response = md5( - `${HA1}:${authDetails.nonce}:${nonceCount}:${cnonce}:auth:${HA2}` - ); + let response; + if (authDetails.qop && authDetails.qop.toLowerCase().includes('auth')) { + console.debug("Using QOP 'auth' for Digest Authentication"); + response = md5( + `${HA1}:${authDetails.nonce}:${nonceCount}:${cnonce}:auth:${HA2}` + ); + } else { + console.debug("No QOP specified, using simple digest"); + response = md5( + `${HA1}:${authDetails.nonce}:${HA2}` + ); + } const headerFields = [ `username="${username}"`, `realm="${authDetails.realm}"`, `nonce="${authDetails.nonce}"`, `uri="${uri}"`, - `qop="auth"`, - `algorithm="${authDetails.algorithm}"`, `response="${response}"`, - `nc="${nonceCount}"`, - `cnonce="${cnonce}"`, ]; + if (authDetails.qop && authDetails.qop.toLowerCase().includes('auth')) { + headerFields.push( + `qop="auth"`, + `algorithm="${authDetails.algorithm}"`, + `nc="${nonceCount}"`, + `cnonce="${cnonce}"`, + ); + } + if (authDetails.opaque) { headerFields.push(`opaque="${authDetails.opaque}"`); } From 5c9a391cc64832f0eec1a3331283ae721ee23534 Mon Sep 17 00:00:00 2001 From: Pragadesh-45 Date: Tue, 7 Oct 2025 17:39:38 +0545 Subject: [PATCH 2/3] fix(digest-auth): handle multiple QOP values in Digest Auth --- packages/bruno-requests/src/auth/digestauth-helper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-requests/src/auth/digestauth-helper.js b/packages/bruno-requests/src/auth/digestauth-helper.js index 4499555a7..646c32013 100644 --- a/packages/bruno-requests/src/auth/digestauth-helper.js +++ b/packages/bruno-requests/src/auth/digestauth-helper.js @@ -100,7 +100,7 @@ export function addDigestInterceptor(axiosInstance, request) { const HA1 = md5(`${username}:${authDetails.realm}:${password}`); const HA2 = md5(`${method}:${uri}`); let response; - if (authDetails.qop && authDetails.qop.toLowerCase().includes('auth')) { + if (authDetails.qop && authDetails.qop.split(',').map((q) => q.trim().toLowerCase()).includes('auth')) { console.debug("Using QOP 'auth' for Digest Authentication"); response = md5( `${HA1}:${authDetails.nonce}:${nonceCount}:${cnonce}:auth:${HA2}` @@ -120,7 +120,7 @@ export function addDigestInterceptor(axiosInstance, request) { `response="${response}"`, ]; - if (authDetails.qop && authDetails.qop.toLowerCase().includes('auth')) { + if (authDetails.qop && authDetails.qop.split(',').map((q) => q.trim().toLowerCase()).includes('auth')) { headerFields.push( `qop="auth"`, `algorithm="${authDetails.algorithm}"`, From 3a04d43ffefafdd91013009cb65425a220cfa39b Mon Sep 17 00:00:00 2001 From: Pragadesh-45 Date: Tue, 7 Oct 2025 18:05:46 +0545 Subject: [PATCH 3/3] fix: lint --- .../src/auth/digestauth-helper.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/bruno-requests/src/auth/digestauth-helper.js b/packages/bruno-requests/src/auth/digestauth-helper.js index 646c32013..e104b795f 100644 --- a/packages/bruno-requests/src/auth/digestauth-helper.js +++ b/packages/bruno-requests/src/auth/digestauth-helper.js @@ -101,15 +101,11 @@ export function addDigestInterceptor(axiosInstance, request) { const HA2 = md5(`${method}:${uri}`); let response; if (authDetails.qop && authDetails.qop.split(',').map((q) => q.trim().toLowerCase()).includes('auth')) { - console.debug("Using QOP 'auth' for Digest Authentication"); - response = md5( - `${HA1}:${authDetails.nonce}:${nonceCount}:${cnonce}:auth:${HA2}` - ); + console.debug('Using QOP \'auth\' for Digest Authentication'); + response = md5(`${HA1}:${authDetails.nonce}:${nonceCount}:${cnonce}:auth:${HA2}`); } else { - console.debug("No QOP specified, using simple digest"); - response = md5( - `${HA1}:${authDetails.nonce}:${HA2}` - ); + console.debug('No QOP specified, using simple digest'); + response = md5(`${HA1}:${authDetails.nonce}:${HA2}`); } const headerFields = [ @@ -121,12 +117,7 @@ export function addDigestInterceptor(axiosInstance, request) { ]; if (authDetails.qop && authDetails.qop.split(',').map((q) => q.trim().toLowerCase()).includes('auth')) { - headerFields.push( - `qop="auth"`, - `algorithm="${authDetails.algorithm}"`, - `nc="${nonceCount}"`, - `cnonce="${cnonce}"`, - ); + headerFields.push(`qop="auth"`, `algorithm="${authDetails.algorithm}"`, `nc="${nonceCount}"`, `cnonce="${cnonce}"`); } if (authDetails.opaque) {