Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/six-rules-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

Pass through credentials when fetching in load
1 change: 1 addition & 0 deletions packages/kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@types/rimraf": "^3.0.0",
"@types/sade": "^1.7.2",
"amphtml-validator": "^1.0.34",
"cookie": "^0.4.1",
"devalue": "^2.0.1",
"eslint": "^7.21.0",
"kleur": "^4.1.4",
Expand Down
22 changes: 15 additions & 7 deletions packages/kit/src/runtime/server/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,6 @@ async function get_response({ request, options, $session, route, status = 200, e

const parsed = parse(url);

// TODO: fix type https://github.com/node-fetch/node-fetch/issues/1113
if (opts.credentials !== 'omit') {
uses_credentials = true;
}

let response;

if (parsed.protocol) {
Expand Down Expand Up @@ -121,11 +116,24 @@ async function get_response({ request, options, $session, route, status = 200, e
}

if (!response) {
const headers = /** @type {import('types.internal').Headers} */ ({ ...opts.headers });

// TODO: fix type https://github.com/node-fetch/node-fetch/issues/1113
if (opts.credentials !== 'omit') {
uses_credentials = true;

headers.cookie = request.headers.cookie;

if (!headers.authorization) {
headers.authorization = request.headers.authorization;
}
}

const rendered = await ssr(
{
host: request.host,
method: opts.method || 'GET',
headers: /** @type {import('types.internal').Headers} */ (opts.headers || {}), // TODO inject credentials...
headers,
path: resolved,
body: /** @type {any} */ (opts.body),
query: new URLSearchParams(parsed.query || '')
Expand Down Expand Up @@ -159,7 +167,7 @@ async function get_response({ request, options, $session, route, status = 200, e
/** @type {import('types.internal').Headers} */
const headers = {};
response.headers.forEach((value, key) => {
if (key !== 'etag') headers[key] = value;
if (key !== 'etag' && key !== 'set-cookie') headers[key] = value;
});

// prettier-ignore
Expand Down
27 changes: 24 additions & 3 deletions packages/kit/test/apps/basics/src/hooks.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
export function getContext() {
import cookie from 'cookie';

/** @type {import('../../../../types').GetContext} */
export function getContext(request) {
const cookies = cookie.parse(request.headers.cookie || '');

return {
answer: 42
answer: 42,
name: cookies.name
};
}

/** @param {any} context */
/** @type {import('../../../../types').GetSession} */
export function getSession({ context }) {
return context;
}

/** @type {import('../../../../types').Handle} */
export async function handle(request, render) {
const response = await render(request);

if (response) {
return {
...response,
headers: {
...response.headers,
'Set-Cookie': 'name=SvelteKit; path=/; HttpOnly'
}
};
}
}
9 changes: 9 additions & 0 deletions packages/kit/test/apps/basics/src/routes/load/__tests__.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,13 @@ export default function (test, is_dev) {

server.close();
});

test(
'makes credentialed fetches to endpoints by default',
'/load',
async ({ page, clicknav }) => {
await clicknav('[href="/load/fetch-credentialed"]');
assert.equal(await page.textContent('h1'), 'Hello SvelteKit!');
}
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function get(request) {
return {
body: {
name: request.context.name
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script context="module">
/** @type {import('../../../../../../types').Load} */
export async function load({ fetch }) {
const res = await fetch('/load/fetch-credentialed.json');

/** @type {any} */
const { name } = await res.json();

return {
props: {
name
}
};
}
</script>

<script>
/** @type {string} */
export let name;
</script>

<h1>Hello {name}!</h1>
1 change: 1 addition & 0 deletions packages/kit/test/apps/basics/src/routes/load/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@
<h1>bar == {foo}?</h1>

<a href="/load/fetch-request">fetch request</a>
<a href="/load/fetch-credentialed">fetch credentialed</a>
<a href="/load/large-response">large response</a>
14 changes: 13 additions & 1 deletion packages/kit/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,26 @@ import { load_config } from '../src/core/load_config/index.js';
import { fileURLToPath, pathToFileURL } from 'url';

async function setup({ port }) {
const base = `http://localhost:${port}`;

const browser = await chromium.launch();

const contexts = {
js: await browser.newContext({ javaScriptEnabled: true }),
nojs: await browser.newContext({ javaScriptEnabled: false })
};

const cookie = {
name: 'name',
value: 'SvelteKit',
domain: base,
path: '/',
httpOnly: true
};

await contexts.js.addCookies([cookie]);
await contexts.nojs.addCookies([cookie]);

const pages = {
js: await contexts.js.newPage(),
nojs: await contexts.nojs.newPage()
Expand Down Expand Up @@ -49,7 +62,6 @@ async function setup({ port }) {

return requests;
};
const base = `http://localhost:${port}`;

// Uncomment this for debugging
// pages.js.on('console', (msg) => {
Expand Down
3 changes: 2 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.