Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: solve issues with basic auth username:password in URLs #11179

Merged
merged 8 commits into from
Jan 9, 2024
5 changes: 5 additions & 0 deletions .changeset/long-adults-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: solve issues with basic auth username:password in URLs (#10522)
Rich-Harris marked this conversation as resolved.
Show resolved Hide resolved
38 changes: 24 additions & 14 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,16 +244,26 @@ export async function start(_app, _target, hydrate) {
current_history_index = current_navigation_index = Date.now();

// create initial history entry, so we can return here
original_replace_state.call(
history,
{
...history.state,
[HISTORY_INDEX]: current_history_index,
[NAVIGATION_INDEX]: current_navigation_index
},
'',
location.href
);
try {
original_replace_state.call(
history,
{
...history.state,
[HISTORY_INDEX]: current_history_index,
[NAVIGATION_INDEX]: current_navigation_index
},
''
);
} catch (error) {
// detect if the issue has been created by basic auth credentials in the current URL
// https://github.com/sveltejs/kit/issues/10522
// if so, refresh the page without credentials
const url = new URL(document.URL);
if (!(url.username || url.password)) {
throw error;
}
location.href = `${location.href}`;
}
Copy link
Member

Choose a reason for hiding this comment

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

we should remove the try-catch, and add the URL check (document.URL !== location.href should work, I think) at the top of start

Suggested change
try {
original_replace_state.call(
history,
{
...history.state,
[HISTORY_INDEX]: current_history_index,
[NAVIGATION_INDEX]: current_navigation_index
},
''
);
} catch (error) {
// detect if the issue has been created by basic auth credentials in the current URL
// https://github.com/sveltejs/kit/issues/10522
// if so, refresh the page without credentials
const url = new URL(document.URL);
if (!(url.username || url.password)) {
throw error;
}
location.href = `${location.href}`;
}
original_replace_state.call(
history,
{
...history.state,
[HISTORY_INDEX]: current_history_index,
[NAVIGATION_INDEX]: current_navigation_index
},
''
);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we keep the (url.username || url.password) check, just in case we are missing another reason why location.href and document.URL? I really can't think of any other scenario, but I have to admit my knowledge of the spec is limited. It would result in something like

if (document.URL !== location.href) {
    const url = new URL(document.URL);
    if (url.username || url.password) {
        location.href = `${location.href}`;
    }
}

Copy link
Member

Choose a reason for hiding this comment

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

My inclination in these cases is to do the simpler thing that we're fairly sure is correct, rather than the more defensive thing. If it turns out there are other cases where document.URL and location.href differ, we'll find out about them soon enough, but if the defensive code is unnecessary we'll never find out — we'll just ship extra code to every SvelteKit app user for no good reason

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense

}

// if we reload the page, or Cmd-Shift-T back to it,
Expand Down Expand Up @@ -682,10 +692,10 @@ async function load_node({ loader, parent, url, params, route, server_data_node
typeof data !== 'object'
? `a ${typeof data}`
: data instanceof Response
? 'a Response object'
: Array.isArray(data)
? 'an array'
: 'a non-plain object'
? 'a Response object'
: Array.isArray(data)
? 'an array'
: 'a non-plain object'
Copy link
Member

Choose a reason for hiding this comment

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

looks like you'll need to pnpm install to get the latest version of Prettier before running pnpm format (annoying, I know)

}, but must return a plain object at the top level (i.e. \`return {...}\`)`
);
}
Expand Down