@@ -26,7 +26,7 @@ import TimeFormatter from '../../../components/intl/TimeFormatter'; | |||
import { Button } from '../../../components/ui/buttons'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import InstanceMessage from '../../../components/common/InstanceMessage'; | |||
import { getBaseUrl } from '../../../helpers/urls'; | |||
import { getBaseUrl, getReturnUrl } from '../../../helpers/urls'; | |||
import { isSonarCloud } from '../../../helpers/system'; | |||
import '../styles.css'; | |||
@@ -112,7 +112,7 @@ export default class App extends React.PureComponent<Props, State> { | |||
loadPreviousPage = () => { | |||
setInterval(() => { | |||
window.location.href = this.props.location.query['return_to'] || getBaseUrl() + '/'; | |||
window.location.href = getReturnUrl(this.props.location); | |||
}, 2500); | |||
}; | |||
@@ -24,7 +24,7 @@ import LoginSonarCloud from './LoginSonarCloud'; | |||
import { doLogin } from '../../../store/rootActions'; | |||
import { getIdentityProviders } from '../../../api/users'; | |||
import { IdentityProvider } from '../../../app/types'; | |||
import { getBaseUrl } from '../../../helpers/urls'; | |||
import { getReturnUrl } from '../../../helpers/urls'; | |||
import { isSonarCloud } from '../../../helpers/system'; | |||
interface OwnProps { | |||
@@ -68,14 +68,8 @@ class LoginContainer extends React.PureComponent<Props, State> { | |||
this.mounted = false; | |||
} | |||
getReturnUrl = () => { | |||
const { location } = this.props; | |||
const queryReturnTo = location.query['return_to']; | |||
return queryReturnTo ? `${queryReturnTo}${location.hash}` : `${getBaseUrl()}/`; | |||
}; | |||
handleSuccessfulLogin = () => { | |||
window.location.href = this.getReturnUrl(); | |||
window.location.href = getReturnUrl(this.props.location); | |||
}; | |||
handleSubmit = (login: string, password: string) => { | |||
@@ -94,7 +88,7 @@ class LoginContainer extends React.PureComponent<Props, State> { | |||
<LoginSonarCloud | |||
identityProviders={identityProviders} | |||
onSubmit={this.handleSubmit} | |||
returnTo={this.getReturnUrl()} | |||
returnTo={getReturnUrl(location)} | |||
showForm={location.query['advanced'] !== undefined} | |||
/> | |||
); | |||
@@ -104,7 +98,7 @@ class LoginContainer extends React.PureComponent<Props, State> { | |||
<Login | |||
identityProviders={identityProviders} | |||
onSubmit={this.handleSubmit} | |||
returnTo={this.getReturnUrl()} | |||
returnTo={getReturnUrl(location)} | |||
/> | |||
); | |||
} |
@@ -18,12 +18,14 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { | |||
isRelativeUrl, | |||
getComponentIssuesUrl, | |||
getComponentDrilldownUrl, | |||
getPathUrlAsString, | |||
getProjectUrl, | |||
getQualityGatesUrl, | |||
getQualityGateUrl | |||
getQualityGateUrl, | |||
getReturnUrl | |||
} from '../urls'; | |||
const SIMPLE_COMPONENT_KEY = 'sonarqube'; | |||
@@ -117,3 +119,21 @@ describe('#getQualityGate(s)Url', () => { | |||
}); | |||
}); | |||
}); | |||
describe('#getReturnUrl', () => { | |||
it('should get the return url', () => { | |||
expect(getReturnUrl({ query: { return_to: '/test' } })).toBe('/test'); | |||
expect(getReturnUrl({ query: { return_to: 'http://www.google.com' } })).toBe('/'); | |||
expect(getReturnUrl({})).toBe('/'); | |||
}); | |||
}); | |||
describe('#isRelativeUrl', () => { | |||
it('should check a relative url', () => { | |||
expect(isRelativeUrl('/test')).toBeTruthy(); | |||
expect(isRelativeUrl('http://www.google.com')).toBeFalsy(); | |||
expect(isRelativeUrl('javascript:alert("test")')).toBeFalsy(); | |||
expect(isRelativeUrl('\\test')).toBeFalsy(); | |||
expect(isRelativeUrl('//test')).toBeFalsy(); | |||
}); | |||
}); |
@@ -252,3 +252,16 @@ export function getHomePageUrl(homepage: HomePage) { | |||
// should never happen, but just in case... | |||
return '/projects'; | |||
} | |||
export function getReturnUrl(location: { hash?: string; query?: { return_to?: string } }) { | |||
const returnTo = location.query && location.query['return_to']; | |||
if (isRelativeUrl(returnTo)) { | |||
return returnTo + (location.hash ? location.hash : ''); | |||
} | |||
return getBaseUrl() + '/'; | |||
} | |||
export function isRelativeUrl(url?: string): boolean { | |||
const regex = new RegExp(/^\/[^/\\]/); | |||
return Boolean(url && regex.test(url)); | |||
} |