diff --git a/components/dashboard/src/App.test.ts b/components/dashboard/src/App.test.ts new file mode 100644 index 00000000000000..9a99656f4b2c98 --- /dev/null +++ b/components/dashboard/src/App.test.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2021 Gitpod GmbH. All rights reserved. + * Licensed under the GNU Affero General Public License (AGPL). + * See License-AGPL.txt in the project root for license information. + */ + +import { getURLHash } from './App' + +test('urlHash', () => { + global.window = Object.create(window); + Object.defineProperty(window, 'location', { + value: { + hash: '#example.org' + } + }); + + expect(getURLHash()).toBe('example.org'); +}); \ No newline at end of file diff --git a/components/dashboard/src/App.tsx b/components/dashboard/src/App.tsx index bc61e206a75e5f..2ffb3ab03fbbd4 100644 --- a/components/dashboard/src/App.tsx +++ b/components/dashboard/src/App.tsx @@ -85,7 +85,7 @@ function isWebsiteSlug(pathName: string) { return slugs.some(slug => pathName.startsWith('/' + slug + '/') || pathName === ('/' + slug)); } -function getURLHash() { +export function getURLHash() { return window.location.hash.replace(/^[#/]+/, ''); } diff --git a/components/dashboard/src/Login.tsx b/components/dashboard/src/Login.tsx index 115c964b094b04..b95e366356255d 100644 --- a/components/dashboard/src/Login.tsx +++ b/components/dashboard/src/Login.tsx @@ -21,6 +21,7 @@ import customize from "./images/welcome/customize.svg"; import fresh from "./images/welcome/fresh.svg"; import prebuild from "./images/welcome/prebuild.svg"; import exclamation from "./images/exclamation.svg"; +import { getURLHash } from "./App"; function Item(props: { icon: string, iconSize?: string, text: string }) { @@ -46,10 +47,18 @@ export function hasVisitedMarketingWebsiteBefore() { export function Login() { const { setUser } = useContext(UserContext); const { setTeams } = useContext(TeamsContext); - const showWelcome = !hasLoggedInBefore() && !hasVisitedMarketingWebsiteBefore(); + const urlHash = getURLHash(); + let hostFromContext: string | undefined; + try { + hostFromContext = urlHash.length > 0 ? new URL(urlHash).host : undefined; + } catch (error) { + // Hash is not a valid URL + } - const [ authProviders, setAuthProviders ] = useState([]); - const [ errorMessage, setErrorMessage ] = useState(undefined); + const [authProviders, setAuthProviders] = useState([]); + const [errorMessage, setErrorMessage] = useState(undefined); + const [providerFromContext, setProviderFromContext] = useState(); + const showWelcome = !hasLoggedInBefore() && !hasVisitedMarketingWebsiteBefore() && !urlHash.startsWith("https://"); useEffect(() => { (async () => { @@ -57,6 +66,13 @@ export function Login() { })(); }, []) + useEffect(() => { + if (hostFromContext && authProviders) { + const providerFromContext = authProviders.find(provider => provider.host === hostFromContext); + setProviderFromContext(providerFromContext); + } + }, [authProviders]) + const authorizeSuccessful = async (payload?: string) => { updateUser().catch(console.error); // Check for a valid returnTo in payload @@ -69,7 +85,7 @@ export function Login() { const updateUser = async () => { await getGitpodService().reconnect(); - const [ user, teams ] = await Promise.all([ + const [user, teams] = await Promise.all([ getGitpodService().server.getLoggedInUser(), getGitpodService().server.getTeams(), ]); @@ -138,19 +154,35 @@ export function Login() {
Gitpod's logo
+
-

Log in{showWelcome ? '' : ' to Gitpod'}

-

ALWAYS READY-TO-CODE

+ {providerFromContext + ? <> +

Log in / Sign up

+

Open a cloud-based environment for

+

{urlHash}

+ + : <> +

Log in{showWelcome ? '' : ' to Gitpod'}

+

ALWAYS READY-TO-CODE

+ }
+ +
- {authProviders.map(ap => { - return ( - - ); - })} + : + authProviders.map(ap => + ) + }
{errorMessage && (