Skip to content

#bsq -- feat: implement URL-embedded credentials handling for authentication for digest-auth#7661

Open
Pragadesh-45 wants to merge 1 commit intousebruno:mainfrom
Pragadesh-45:fix/7560
Open

#bsq -- feat: implement URL-embedded credentials handling for authentication for digest-auth#7661
Pragadesh-45 wants to merge 1 commit intousebruno:mainfrom
Pragadesh-45:fix/7560

Conversation

@Pragadesh-45
Copy link
Copy Markdown
Contributor

@Pragadesh-45 Pragadesh-45 commented Apr 2, 2026

fixes: #7560

Description

This PR fixes Digest Authentication not working when credentials are embedded in the URL (e.g. https://admin:password@host/path) with auth: none.

When credentials are embedded in the URL, Bruno never populated digestConfig, so the Digest interceptor was never registered and Digest challenges went unhandled. Even when digestConfig was set
explicitly, axios would auto-add an Authorization: Basic header from the URL credentials, which caused the interceptor's containsAuthorizationHeader check to bail out before the Digest retry could
happen.

This PR fixes the issue by extracting URL-embedded credentials in prepare-request.js and setting both basicAuth (for preemptive Basic auth) and digestConfig (to register the Digest interceptor as a
fallback). The URL credential stripping is moved inside the interceptor's error handler so it only fires after a Digest challenge is confirmed — preserving native Basic auth behaviour when the server
accepts credentials on the first request.

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.
image

Summary by CodeRabbit

  • New Features

    • Support for authentication using credentials embedded in request URLs (e.g., https://user:pass@host), including percent-decoded handling and correct behavior for Basic and Digest flows.
  • Tests

    • Added coverage validating URL-embedded credential handling for Basic and Digest authentication, including success/failure and precedence scenarios.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

Walkthrough

URL-embedded credentials (user:pass@host) are now detected and parsed when no explicit per-request basicAuth or digestConfig exists. Parsed, percent-decoded credentials populate basicAuth (for preemptive Basic) and digestConfig (as Digest fallback). The digest interceptor now treats URL credentials as fallback, strips credentials from retried URLs, and removes conflicting Authorization headers before retry. Tests and collection items added to cover basic and digest scenarios.

Changes

Cohort / File(s) Summary
Prepare Request (CLI & Electron)
packages/bruno-cli/src/runner/prepare-request.js, packages/bruno-electron/src/ipc/network/prepare-request.js
Detect and parse URL-embedded username:password when no request basicAuth/digestConfig exist; percent-decode and set both basicAuth and digestConfig; swallow parse errors.
Prepare Request Tests
packages/bruno-cli/tests/runner/prepare-request.spec.js
New tests validating URL credential extraction, percent-decoding, and precedence vs explicit auth.mode (none, basic, digest).
Digest Auth Interceptor
packages/bruno-requests/src/auth/digestauth-helper.js
Use URL-embedded credentials as fallback if digestConfig missing; simplify Digest 401 detection; remove Authorization headers and strip credentials from retried URL prior to computing/applying Digest header; reject if Authorization remains.
Digest Auth Tests
packages/bruno-requests/src/auth/digestauth-helper.spec.js
New tests covering Digest fallback from URL creds, retry URL cleaning, precedence with existing digestConfig, no-401 behavior, and percent-decoded credentials in Digest header.
Bruno Test Collections — Basic via URL
packages/bruno-tests/collection/auth/basic/via url/Basic Auth 200.bru, packages/bruno-tests/collection/auth/basic/via url/Basic Auth 401.bru
Added collection items to validate Basic auth behavior with URL-embedded credentials (200 and 401 cases).
Bruno Test Collections — Digest via URL
packages/bruno-tests/collection/auth/digest/via url/Digest Auth 200.bru, packages/bruno-tests/collection/auth/digest/via url/Digest Auth 401.bru, packages/bruno-tests/collection/auth/digest/via url/folder.bru
Added digest collection items and folder metadata (inherit auth) to validate digest flow with URL-embedded credentials.
Bruno Test Collections — Digest folder metadata
packages/bruno-tests/collection/auth/digest/via auth/Digest Auth 401.bru, packages/bruno-tests/collection/auth/digest/via auth/folder.bru
Resequenced an existing digest test (seq change) and added folder metadata for “via auth”.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant PrepareRequest
    participant URLParser
    participant AxiosConfig

    Client->>PrepareRequest: prepareRequest(item)
    PrepareRequest->>PrepareRequest: Check existing basicAuth / digestConfig
    alt No explicit auth
        PrepareRequest->>URLParser: Parse URL for embedded credentials
        URLParser-->>PrepareRequest: username, password (or null)
        alt Credentials found
            PrepareRequest->>AxiosConfig: Set basicAuth (decoded creds)
            PrepareRequest->>AxiosConfig: Set digestConfig (decoded creds)
        end
    end
    PrepareRequest-->>Client: axiosRequest with auth config
Loading
sequenceDiagram
    participant Request
    participant DigestInterceptor
    participant Server
    participant Retry

    Request->>DigestInterceptor: First request (may include URL creds)
    DigestInterceptor->>Server: Send request
    Server-->>DigestInterceptor: 401 + WWW-Authenticate: Digest
    alt URL-embedded creds available and no digestConfig
        DigestInterceptor->>DigestInterceptor: Remove Authorization header(s)
        DigestInterceptor->>DigestInterceptor: Strip username:password from URL
        DigestInterceptor->>DigestInterceptor: Compute Digest Authorization using decoded URL creds
    end
    DigestInterceptor->>Retry: Retry request with Digest header and cleaned URL
    Retry->>Server: Send retried request
    Server-->>Retry: 200 OK (or 401)
    Retry-->>Request: Return response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • fix: auth in cli #6675 — Modifies packages/bruno-cli/src/runner/prepare-request.js; related at request-preparation layer and may overlap with URL credential extraction changes.

Suggested labels

size/XL

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno

Poem

🔐 Credentials hid in URLs, now found and freed,
Decoded, assigned—basic first, digest as need,
Headers trimmed, retried clean and spry,
Tests added to prove the flow won’t lie,
Network auth dances, bugs take their leave. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR fully addresses issue #7560 by implementing URL-embedded credential extraction in prepare-request.js files (CLI and Electron), registering digestConfig to enable the Digest interceptor, handling URL credential stripping in the error handler, and adding comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are scoped to URL-embedded credentials handling for digest authentication. Test files and configuration files added are directly related to validating the feature with both basic and digest auth scenarios.
Title check ✅ Passed The title clearly identifies the main feature: implementing URL-embedded credentials handling for digest authentication, which aligns with the core changes across multiple files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor Author

@Pragadesh-45 Pragadesh-45 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self Review Done ✅

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/bruno-electron/src/ipc/network/prepare-request.js (1)

524-539: Duplicated logic with CLI, but acceptable here.

This is identical to packages/bruno-cli/src/runner/prepare-request.js (lines 449-464). Given these are in separate packages with different build contexts, and the logic is simple (~15 lines), the duplication is tolerable.

If this pattern expands, consider extracting to a shared utility in bruno-requests.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-electron/src/ipc/network/prepare-request.js` around lines 524
- 539, This block duplicates URL-embedded credential parsing (setting
axiosRequest.basicAuth and axiosRequest.digestConfig) found in the CLI's
prepare-request; leave the code as-is for now but when this pattern appears
elsewhere extract it into a shared utility (e.g., a function named
parseCredentialsFromUrl or extractUrlCredentials in a new bruno-requests helper)
that takes a URL string and returns { username, password } and then replace the
inline logic in prepare-request.js (and packages/bruno-cli) to call that helper
and set axiosRequest.basicAuth and axiosRequest.digestConfig from its result.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bruno-requests/src/auth/digestauth-helper.spec.js`:
- Around line 140-173: The test currently inspects firstRequestHeaders (set in
axiosInstance.defaults.adapter) but Axios doesn’t populate URL-embedded Basic
credentials before the adapter runs, so the assertion is meaningless; update the
test to capture and assert headers from the retry (when callCount === 2) instead
of only the first call: in the adapter save both firstRequestHeaders and
retryRequestHeaders (or just retryRequestHeaders) and after awaiting
axiosInstance(request) assert that retryRequestHeaders.Authorization matches
/^Digest / (and optionally that firstRequestHeaders did not contain a Basic
header), keeping addDigestInterceptor, request, axiosInstance.defaults.adapter
and callCount as the locating symbols to modify.

---

Nitpick comments:
In `@packages/bruno-electron/src/ipc/network/prepare-request.js`:
- Around line 524-539: This block duplicates URL-embedded credential parsing
(setting axiosRequest.basicAuth and axiosRequest.digestConfig) found in the
CLI's prepare-request; leave the code as-is for now but when this pattern
appears elsewhere extract it into a shared utility (e.g., a function named
parseCredentialsFromUrl or extractUrlCredentials in a new bruno-requests helper)
that takes a URL string and returns { username, password } and then replace the
inline logic in prepare-request.js (and packages/bruno-cli) to call that helper
and set axiosRequest.basicAuth and axiosRequest.digestConfig from its result.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f9934a6b-3992-463c-ad2a-3b93cff8b47d

📥 Commits

Reviewing files that changed from the base of the PR and between 55b952f and 72f5c7a.

📒 Files selected for processing (13)
  • packages/bruno-cli/src/runner/prepare-request.js
  • packages/bruno-cli/tests/runner/prepare-request.spec.js
  • packages/bruno-electron/src/ipc/network/prepare-request.js
  • packages/bruno-requests/src/auth/digestauth-helper.js
  • packages/bruno-requests/src/auth/digestauth-helper.spec.js
  • packages/bruno-tests/collection/auth/basic/via url/Basic Auth 200.bru
  • packages/bruno-tests/collection/auth/basic/via url/Basic Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via auth/Digest Auth 200.bru
  • packages/bruno-tests/collection/auth/digest/via auth/Digest Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via auth/folder.bru
  • packages/bruno-tests/collection/auth/digest/via url/Digest Auth 200.bru
  • packages/bruno-tests/collection/auth/digest/via url/Digest Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via url/folder.bru

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/bruno-requests/src/auth/digestauth-helper.js (1)

36-36: Consider defensive destructuring for digestConfig.

If addDigestInterceptor is ever called with request.digestConfig as undefined or null, line 36 throws. While current call sites should always provide it, a simple fallback improves robustness:

Suggested fix
-  let { username, password } = request.digestConfig;
+  let { username, password } = request.digestConfig || {};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-requests/src/auth/digestauth-helper.js` at line 36, The
destructuring of request.digestConfig in addDigestInterceptor (let { username,
password } = request.digestConfig) can throw if digestConfig is null/undefined;
update the destructuring to use a safe fallback (e.g., default to an empty
object) and then handle absent username/password appropriately (skip adding the
interceptor or return an error) so the function no longer throws when
request.digestConfig is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/bruno-requests/src/auth/digestauth-helper.js`:
- Line 36: The destructuring of request.digestConfig in addDigestInterceptor
(let { username, password } = request.digestConfig) can throw if digestConfig is
null/undefined; update the destructuring to use a safe fallback (e.g., default
to an empty object) and then handle absent username/password appropriately (skip
adding the interceptor or return an error) so the function no longer throws when
request.digestConfig is missing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 361453ed-256c-4eb6-9adc-5926337ff879

📥 Commits

Reviewing files that changed from the base of the PR and between 72f5c7a and 5066b1f.

📒 Files selected for processing (13)
  • packages/bruno-cli/src/runner/prepare-request.js
  • packages/bruno-cli/tests/runner/prepare-request.spec.js
  • packages/bruno-electron/src/ipc/network/prepare-request.js
  • packages/bruno-requests/src/auth/digestauth-helper.js
  • packages/bruno-requests/src/auth/digestauth-helper.spec.js
  • packages/bruno-tests/collection/auth/basic/via url/Basic Auth 200.bru
  • packages/bruno-tests/collection/auth/basic/via url/Basic Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via auth/Digest Auth 200.bru
  • packages/bruno-tests/collection/auth/digest/via auth/Digest Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via auth/folder.bru
  • packages/bruno-tests/collection/auth/digest/via url/Digest Auth 200.bru
  • packages/bruno-tests/collection/auth/digest/via url/Digest Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via url/folder.bru
✅ Files skipped from review due to trivial changes (9)
  • packages/bruno-tests/collection/auth/digest/via auth/Digest Auth 401.bru
  • packages/bruno-tests/collection/auth/basic/via url/Basic Auth 200.bru
  • packages/bruno-tests/collection/auth/digest/via url/Digest Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via url/Digest Auth 200.bru
  • packages/bruno-tests/collection/auth/basic/via url/Basic Auth 401.bru
  • packages/bruno-tests/collection/auth/digest/via url/folder.bru
  • packages/bruno-tests/collection/auth/digest/via auth/folder.bru
  • packages/bruno-electron/src/ipc/network/prepare-request.js
  • packages/bruno-cli/tests/runner/prepare-request.spec.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-cli/src/runner/prepare-request.js

@Pragadesh-45 Pragadesh-45 changed the title feat: implement URL-embedded credentials handling for authentication for digest-auth #bsq -- feat: implement URL-embedded credentials handling for authentication for digest-auth Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Digest in URL seems not properly handled

1 participant