diff --git a/scripts/server.cjs b/scripts/server.cjs index e1bc764a..61199651 100644 --- a/scripts/server.cjs +++ b/scripts/server.cjs @@ -12,6 +12,17 @@ exports.createServer = function (port, enableAtomics) { if (url.pathname === '/') { res.writeHead(301, { Location: '/tests/' }); return res.end(); + } else if (url.pathname === '/api/cookie') { + const name = url.searchParams.get('name'); + let date = new Date(); + date.setTime(date.getTime() + 24 * 60 * 60 * 1000); // 24 hours from now + let expires = date.toUTCString(); + res.writeHead(200, { + 'Set-Cookie': `${name}=1; Path=/; Domain=localhost; expires=${expires}; SameSite=Lax;`, + 'Access-Control-Allow-Origin': req.headers.origin ? req.headers.origin : '*', + 'Access-Control-Allow-Credentials': 'true', + }); + return res.end(); } else if (url.pathname.endsWith('post')) { res.writeHead(200); let body = ''; diff --git a/src/lib/sandbox/read-main-platform.ts b/src/lib/sandbox/read-main-platform.ts index 832a6762..e3ec55e1 100644 --- a/src/lib/sandbox/read-main-platform.ts +++ b/src/lib/sandbox/read-main-platform.ts @@ -7,12 +7,7 @@ import { serializeConfig, } from '../utils'; import { config, docImpl, libPath, mainWindow } from './main-globals'; -import { - InterfaceType, - InterfaceInfo, - InterfaceMember, - InitWebWorkerData, -} from '../types'; +import { InterfaceType, InterfaceInfo, InterfaceMember, InitWebWorkerData } from '../types'; export const readMainPlatform = () => { const elm = docImpl.createElement('i'); @@ -66,7 +61,7 @@ export const readMainPlatform = () => { $config$, $interfaces$: readImplementations(impls, initialInterfaces), $libPath$: new URL(libPath, mainWindow.location as any) + '', - $origin$: origin + $origin$: origin, }; addGlobalConstructorUsingPrototype( diff --git a/src/lib/types.ts b/src/lib/types.ts index 3b6b22ed..b9c792c7 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -448,6 +448,11 @@ export interface PartytownConfig { get?: GetHook; set?: SetHook; apply?: ApplyHook; + /** + * When set to true, the Partytown Web Worker will respect the `withCredentials` option of XMLHttpRequests. + * Default: false + */ + allowXhrCredentials?: boolean; /** * An absolute path to the root directory which Partytown library files * can be found. The library path must start and end with a `/`. diff --git a/src/lib/web-worker/init-web-worker.ts b/src/lib/web-worker/init-web-worker.ts index 5d9320bb..4003c789 100644 --- a/src/lib/web-worker/init-web-worker.ts +++ b/src/lib/web-worker/init-web-worker.ts @@ -1,7 +1,4 @@ -import { - commaSplit, - webWorkerCtx, -} from './worker-constants'; +import { commaSplit, webWorkerCtx } from './worker-constants'; import type { InitWebWorkerData, PartytownInternalConfig } from '../types'; export const initWebWorker = (initWebWorkerData: InitWebWorkerData) => { diff --git a/src/lib/web-worker/worker-storage.ts b/src/lib/web-worker/worker-storage.ts index 67ac082b..37fa9c02 100644 --- a/src/lib/web-worker/worker-storage.ts +++ b/src/lib/web-worker/worker-storage.ts @@ -52,7 +52,7 @@ export const addStorageApi = ( get length() { if (isSameOrigin) { - return getter(win, [storageName, 'length']) + return getter(win, [storageName, 'length']); } else { warnCrossOrigin('length', storageName, env); } diff --git a/src/lib/web-worker/worker-window.ts b/src/lib/web-worker/worker-window.ts index 594655b7..025e0085 100644 --- a/src/lib/web-worker/worker-window.ts +++ b/src/lib/web-worker/worker-window.ts @@ -587,7 +587,11 @@ export const createWindow = ( args[1] = resolveUrl(env, args[1], 'xhr'); (super.open as any)(...args); } - set withCredentials(_: any) {} + set withCredentials(_: boolean) { + if (webWorkerCtx.$config$.allowXhrCredentials) { + super.withCredentials = _; + } + } toString() { return str; } diff --git a/tests/platform/fetch/fetch.spec.ts b/tests/platform/fetch/fetch.spec.ts index df7af159..73068812 100644 --- a/tests/platform/fetch/fetch.spec.ts +++ b/tests/platform/fetch/fetch.spec.ts @@ -13,6 +13,10 @@ test('fetch', async ({ page }) => { const testFetchJson = page.locator('#testFetchJson'); await expect(testFetchJson).toHaveText('{"mph":88}'); + await page.waitForSelector('.testFetchCookie'); + const testFetchCookie = page.locator('#testFetchCookie'); + await expect(testFetchCookie).toContainText('server-test-fetch=1'); + await page.waitForSelector('.testXMLHttpRequest'); const testXMLHttpRequest = page.locator('#testXMLHttpRequest'); await expect(testXMLHttpRequest).toHaveText('text'); @@ -22,4 +26,8 @@ test('fetch', async ({ page }) => { const testXMLHttpRequestCstrNative = page.locator('#testXMLHttpRequestCstrNative'); await expect(testXMLHttpRequestCstrNative).toHaveText('true'); + + await page.waitForSelector('.testXMLHttpRequestCookie'); + const testXMLHttpRequestCookie = page.locator('#testXMLHttpRequestCookie'); + await expect(testXMLHttpRequestCookie).toContainText('server-test-xhr=1'); }); diff --git a/tests/platform/fetch/index.html b/tests/platform/fetch/index.html index 2f5870bb..d8984cd1 100644 --- a/tests/platform/fetch/index.html +++ b/tests/platform/fetch/index.html @@ -91,6 +91,24 @@

fetch() / XMLHttpRequest

+
  • + fetch Set-Cookie + + + + +
  • +
  • XMLHttpRequest @@ -161,6 +179,27 @@

    fetch() / XMLHttpRequest

  • +
  • + XMLHttpRequest Set-Cookie + + + + +
  • +