From 257861bd6e3f7de77a4c7ede64e9538370c0a2ed Mon Sep 17 00:00:00 2001 From: Chris Breiding Date: Wed, 29 Nov 2023 22:40:02 -0500 Subject: [PATCH] fix: Fix issue with using privileged commands when baseUrl includes basic auth credentials (#28428) --- cli/CHANGELOG.md | 3 ++- .../lib/privileged-commands/privileged-channel.js | 6 +++++- .../test/unit/browsers/privileged-channel_spec.js | 3 +++ .../privileged-commands/cypress.config.js | 13 +++++++++++++ .../privileged-commands/cypress/e2e/spec.cy.js | 7 +++++++ .../cypress/fixtures/example.json | 5 +++++ system-tests/test/base_url_spec.js | 15 +++++++++++++++ 7 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 system-tests/projects/privileged-commands/cypress.config.js create mode 100644 system-tests/projects/privileged-commands/cypress/e2e/spec.cy.js create mode 100644 system-tests/projects/privileged-commands/cypress/fixtures/example.json diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 9317000e8d18..45a27f6fc002 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -7,7 +7,8 @@ _Released 12/5/2023 (PENDING)_ - Fixed an issue where pages or downloads opened in a new tab were missing basic auth headers. Fixes [#28350](https://github.com/cypress-io/cypress/issues/28350). - Fixed an issue where request logging would default the `message` to the `args` of the currently running command even though those `args` would not apply to the request log and are not displayed. If the `args` are sufficiently large (e.g. when running the `cy.task` from the [code-coverage](https://github.com/cypress-io/code-coverage/) plugin) there could be performance/memory implications. Addressed in [#28411](https://github.com/cypress-io/cypress/pull/28411). -- Fixed issue where some URLs would timeout in pre-request correlation. Addressed in [#28427](https://github.com/cypress-io/cypress/pull/28427). +- Fixed an issue where commands would fail with the error `must only be invoked from the spec file or support file` if the project's `baseUrl` included basic auth credentials. Fixes [#28336](https://github.com/cypress-io/cypress/issues/28336). +- Fixed an issue where some URLs would timeout in pre-request correlation. Addressed in [#28427](https://github.com/cypress-io/cypress/pull/28427). **Misc:** diff --git a/packages/server/lib/privileged-commands/privileged-channel.js b/packages/server/lib/privileged-commands/privileged-channel.js index b89b882d4e98..7f4eec37e2e2 100644 --- a/packages/server/lib/privileged-commands/privileged-channel.js +++ b/packages/server/lib/privileged-commands/privileged-channel.js @@ -199,7 +199,11 @@ // send it to the server, where it's stored in state. when the command is // run and it sends its message to the server via websocket, we check // that verified status before allowing the command to continue running - const promise = fetch(`/${namespace}/add-verified-command`, { + // + // needs to use the fully-qualified url or else when the baseUrl includes + // basic auth, the fetch fails with a security error + // see https://github.com/cypress-io/cypress/issues/28336 + const promise = fetch(`${win.location.origin}/${namespace}/add-verified-command`, { body: stringify({ args, name: command.name, diff --git a/packages/server/test/unit/browsers/privileged-channel_spec.js b/packages/server/test/unit/browsers/privileged-channel_spec.js index b945ab629831..b8777c3a5c63 100644 --- a/packages/server/test/unit/browsers/privileged-channel_spec.js +++ b/packages/server/test/unit/browsers/privileged-channel_spec.js @@ -36,6 +36,9 @@ describe('privileged channel', () => { Function: { prototype: { toString: Function.prototype.toString, } }, + location: { + origin: 'http://localhost:1234', + }, Math: { imul: Math.imul, }, diff --git a/system-tests/projects/privileged-commands/cypress.config.js b/system-tests/projects/privileged-commands/cypress.config.js new file mode 100644 index 000000000000..deba5ef5a25f --- /dev/null +++ b/system-tests/projects/privileged-commands/cypress.config.js @@ -0,0 +1,13 @@ +module.exports = { + e2e: { + baseUrl: 'http://user:pass@localhost:9999/app', + supportFile: false, + setupNodeEvents (on) { + on('task', { + 'return:arg' (arg) { + return arg + }, + }) + }, + }, +} diff --git a/system-tests/projects/privileged-commands/cypress/e2e/spec.cy.js b/system-tests/projects/privileged-commands/cypress/e2e/spec.cy.js new file mode 100644 index 000000000000..9bfb7fe7a7ff --- /dev/null +++ b/system-tests/projects/privileged-commands/cypress/e2e/spec.cy.js @@ -0,0 +1,7 @@ +it('can run privileged commands with basic auth baseUrl', () => { + cy.visit('/html') + cy.exec('echo "hello"') + cy.readFile('cypress/fixtures/example.json') + cy.writeFile('cypress/_test-output/written.txt', 'contents') + cy.task('return:arg', 'arg') +}) diff --git a/system-tests/projects/privileged-commands/cypress/fixtures/example.json b/system-tests/projects/privileged-commands/cypress/fixtures/example.json new file mode 100644 index 000000000000..02e4254378e9 --- /dev/null +++ b/system-tests/projects/privileged-commands/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/system-tests/test/base_url_spec.js b/system-tests/test/base_url_spec.js index 38ae2717e6b6..dbdbae9e8f3c 100644 --- a/system-tests/test/base_url_spec.js +++ b/system-tests/test/base_url_spec.js @@ -48,6 +48,21 @@ describe('e2e baseUrl', () => { }) }) + // https://github.com/cypress-io/cypress/issues/28336 + context('basic auth + privileged commands', () => { + systemTests.setup({ + servers: { + port: 9999, + onServer, + }, + }) + + systemTests.it('passes', { + browser: 'chrome', + project: 'privileged-commands', + }) + }) + context('http', () => { systemTests.setup({ servers: {