Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit69c1d98

Browse files
authored
fix(site): sanitize login redirect (#15208)
1 parent7efdf81 commit69c1d98

File tree

2 files changed

+30
-37
lines changed

2 files changed

+30
-37
lines changed

‎site/src/pages/LoginPage/LoginPage.tsx

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ export const LoginPage: FC = () => {
2828
constnavigate=useNavigate();
2929
const{ metadata}=useEmbeddedMetadata();
3030
constbuildInfoQuery=useQuery(buildInfo(metadata["build-info"]));
31+
letredirectError:Error|null=null;
32+
letredirectUrl:URL|null=null;
33+
try{
34+
redirectUrl=newURL(redirectTo);
35+
}catch{
36+
// Do nothing
37+
}
38+
39+
constisApiRouteRedirect=redirectTo.startsWith("/api/v2");
3140

3241
useEffect(()=>{
3342
if(!buildInfoQuery.data||isSignedIn){
@@ -42,41 +51,24 @@ export const LoginPage: FC = () => {
4251
},[isSignedIn,buildInfoQuery.data,user?.id]);
4352

4453
if(isSignedIn){
45-
if(buildInfoQuery.data){
46-
// This uses `navigator.sendBeacon`, so window.href
47-
// will not stop the request from being sent!
48-
sendDeploymentEvent(buildInfoQuery.data,{
49-
type:"deployment_login",
50-
user_id:user?.id,
51-
});
54+
// The reason we need `window.location.href` for api redirects is that
55+
// we need the page to reload and make a request to the backend. If we
56+
// use `<Navigate>`, react would handle the redirect itself and never
57+
// request the page from the backend.
58+
if(isApiRouteRedirect){
59+
constsanitizedUrl=newURL(redirectTo,window.location.origin);
60+
window.location.href=sanitizedUrl.pathname+sanitizedUrl.search;
61+
// Setting the href should immediately request a new page. Show an
62+
// error state if it doesn't.
63+
redirectError=newError("unable to redirect");
64+
}else{
65+
return(
66+
<Navigate
67+
to={redirectUrl ?redirectUrl.pathname :redirectTo}
68+
replace
69+
/>
70+
);
5271
}
53-
54-
// If the redirect is going to a workspace application, and we
55-
// are missing authentication, then we need to change the href location
56-
// to trigger a HTTP request. This allows the BE to generate the auth
57-
// cookie required. Similarly for the OAuth2 exchange as the authorization
58-
// page is served by the backend.
59-
// If no redirect is present, then ignore this branched logic.
60-
if(redirectTo!==""&&redirectTo!=="/"){
61-
try{
62-
// This catches any absolute redirects. Relative redirects
63-
// will fail the try/catch. Subdomain apps are absolute redirects.
64-
constredirectURL=newURL(redirectTo);
65-
if(redirectURL.host!==window.location.host){
66-
window.location.href=redirectTo;
67-
returnnull;
68-
}
69-
}catch{
70-
// Do nothing
71-
}
72-
// Path based apps and OAuth2.
73-
if(redirectTo.includes("/apps/")||redirectTo.includes("/oauth2/")){
74-
window.location.href=redirectTo;
75-
returnnull;
76-
}
77-
}
78-
79-
return<Navigateto={redirectTo}replace/>;
8072
}
8173

8274
if(isConfiguringTheFirstUser){
@@ -90,14 +82,15 @@ export const LoginPage: FC = () => {
9082
</Helmet>
9183
<LoginPageView
9284
authMethods={authMethodsQuery.data}
93-
error={signInError}
85+
error={signInError??redirectError}
9486
isLoading={isLoading||authMethodsQuery.isLoading}
9587
buildInfo={buildInfoQuery.data}
9688
isSigningIn={isSigningIn}
9789
onSignIn={async({ email, password})=>{
9890
awaitsignIn(email,password);
9991
navigate("/");
10092
}}
93+
redirectTo={redirectTo}
10194
/>
10295
</>
10396
);

‎site/src/pages/LoginPage/LoginPageView.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { CustomLogo } from "components/CustomLogo/CustomLogo";
55
import{Loader}from"components/Loader/Loader";
66
import{typeFC,useState}from"react";
77
import{useLocation}from"react-router-dom";
8-
import{retrieveRedirect}from"utils/redirect";
98
import{SignInForm}from"./SignInForm";
109
import{TermsOfServiceLink}from"./TermsOfServiceLink";
1110

@@ -16,6 +15,7 @@ export interface LoginPageViewProps {
1615
buildInfo?:BuildInfoResponse;
1716
isSigningIn:boolean;
1817
onSignIn:(credentials:{email:string;password:string})=>void;
18+
redirectTo:string;
1919
}
2020

2121
exportconstLoginPageView:FC<LoginPageViewProps>=({
@@ -25,9 +25,9 @@ export const LoginPageView: FC<LoginPageViewProps> = ({
2525
buildInfo,
2626
isSigningIn,
2727
onSignIn,
28+
redirectTo,
2829
})=>{
2930
constlocation=useLocation();
30-
constredirectTo=retrieveRedirect(location.search);
3131
// This allows messages to be displayed at the top of the sign in form.
3232
// Helpful for any redirects that want to inform the user of something.
3333
constmessage=newURLSearchParams(location.search).get("message");

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp