From 11c7bd15aad218409d2434a1113bcbb58e880cda Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Thu, 30 May 2024 08:27:28 +0000 Subject: [PATCH] Bug 1899389 - [devtools] Use credentials for devtools sourcemap fetch call r=devtools-reviewers,ochameau Differential Revision: https://phabricator.services.mozilla.com/D212059 --- .../browser_dbg-sourcemaps-credentials.js | 111 ++++++++++++++++++ .../debugger/test/mochitest/browser_kz.toml | 2 + .../utils/network-request.js | 3 + 3 files changed, 116 insertions(+) create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-credentials.js diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-credentials.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-credentials.js new file mode 100644 index 000000000000..d74f6a65aa7d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-credentials.js @@ -0,0 +1,111 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests loading sourcemapped sources, setting breakpoints, and +// stepping in them. + +"use strict"; + +const EXPECTED_COOKIE = "credentials=true"; + +// This test checks that the DevTools sourcemap request includes credentials +// from the page. See Bug 1899389. +add_task(async function () { + const httpServer = setupTestServer(); + const port = httpServer.identity.primaryPort; + + const dbg = await initDebuggerWithAbsoluteURL( + `http://localhost:${port}/index.html` + ); + + await waitForSources(dbg, "min.js"); + const minifiedSrc = findSource(dbg, "min.js"); + await selectSource(dbg, minifiedSrc); + + const footerButton = findElement(dbg, "sourceMapFooterButton"); + is( + footerButton.textContent, + "bundle file", + "Sourcemap button mentions the bundle file" + ); + ok(!footerButton.classList.contains("not-mapped")); + + info("Click on jump to original source link from editor's footer"); + const mappedSourceLink = findElement(dbg, "mappedSourceLink"); + is( + mappedSourceLink.textContent, + "From original.js", + "The link to mapped source mentions the original file name" + ); + mappedSourceLink.click(); + + const originalSrc = findSource(dbg, "original.js"); + await waitForSelectedSource(dbg, originalSrc); + info("The original source was successfully selected"); +}); + +function setupTestServer() { + // The test server will serve: + // - index.html: page which loads a min.js file + // - min.js: simple minified js file, linked to the map min.js.map + // - min.js.map: the corresponding sourcemap + // - original.js: the original file + // + // The sourcemap file will only be returned if the request contains a cookie + // set in the page. Otherwise it will return a 404. + + const httpServer = createTestHTTPServer(); + httpServer.registerContentType("html", "text/html"); + httpServer.registerContentType("js", "application/javascript"); + httpServer.registerContentType("map", "text/plain"); + + // Page: index.html + httpServer.registerPathHandler("/index.html", function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + +

Sourcemap with credentials

+ + + + `); + }); + + // Bundle: min.js + httpServer.registerPathHandler("/min.js", function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/javascript", false); + response.write(`function sum(n,u){return n+u} +//# sourceMappingURL=min.js.map +`); + }); + + // Sourcemap: min.js.map + httpServer.registerPathHandler("/min.js.map", function (request, response) { + if ( + request.hasHeader("Cookie") && + request.getHeader("Cookie") == EXPECTED_COOKIE + ) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/javascript", false); + response.write( + `{"version":3,"sources":["original.js"],"names":["sum","first","second"],"mappings":"AAAA,SAASA,IAAIC,EAAOC,GAClB,OAAOD,EAAQC"}` + ); + } else { + response.setStatusLine(request.httpVersion, 404, "Not found"); + } + }); + + // Original: original.js + httpServer.registerPathHandler("/original.js", function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/javascript", false); + response.write(`function sum(first, second) { + return first + second; +}`); + }); + + return httpServer; +} diff --git a/devtools/client/debugger/test/mochitest/browser_kz.toml b/devtools/client/debugger/test/mochitest/browser_kz.toml index 6b39a42b9493..bcb4e04a121e 100644 --- a/devtools/client/debugger/test/mochitest/browser_kz.toml +++ b/devtools/client/debugger/test/mochitest/browser_kz.toml @@ -239,6 +239,8 @@ skip-if = ["os == 'linux' && !asan"] # bug 1447118 ["browser_dbg-sourcemaps-breakpoints.js"] fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled +["browser_dbg-sourcemaps-credentials.js"] + ["browser_dbg-sourcemaps-disabled.js"] ["browser_dbg-sourcemaps-ignorelist.js"] diff --git a/devtools/client/shared/source-map-loader/utils/network-request.js b/devtools/client/shared/source-map-loader/utils/network-request.js index f331dc446ec2..34d3ab923665 100644 --- a/devtools/client/shared/source-map-loader/utils/network-request.js +++ b/devtools/client/shared/source-map-loader/utils/network-request.js @@ -22,6 +22,9 @@ async function networkRequest(url, opts) { const response = await fetch(url, { cache: opts.loadFromCache ? "default" : "no-cache", + // See Bug 1899389, by default fetch calls from the system principal no + // longer use credentials. + credentials: "same-origin", redirect: opts.allowRedirects ? "follow" : "error", });