diff --git a/.changeset/moody-beds-chew.md b/.changeset/moody-beds-chew.md new file mode 100644 index 0000000000..72962eea59 --- /dev/null +++ b/.changeset/moody-beds-chew.md @@ -0,0 +1,5 @@ +--- +'@backstage/core': patch +--- + +Fix a bug where users are asked to log-in on every page refresh. This is specific to people with only one sign-in provider in their SignInPage component. diff --git a/packages/core/src/layout/SignInPage/SignInPage.tsx b/packages/core/src/layout/SignInPage/SignInPage.tsx index daefe40c73..6a8dcf454e 100644 --- a/packages/core/src/layout/SignInPage/SignInPage.tsx +++ b/packages/core/src/layout/SignInPage/SignInPage.tsx @@ -14,18 +14,18 @@ * limitations under the License. */ +import { configApiRef, SignInPageProps, useApi } from '@backstage/core-api'; +import { Button, Grid, Typography } from '@material-ui/core'; import React, { useEffect, useState } from 'react'; -import { Page } from '../Page'; -import { Header } from '../Header'; +import { Progress } from '../../components/Progress'; import { Content } from '../Content/Content'; import { ContentHeader } from '../ContentHeader/ContentHeader'; -import { Grid, Button, Typography } from '@material-ui/core'; -import { SignInPageProps, useApi, configApiRef } from '@backstage/core-api'; -import { useSignInProviders, getSignInProviders } from './providers'; -import { IdentityProviders, SignInProviderConfig } from './types'; -import { Progress } from '../../components/Progress'; -import { GridItem, useStyles } from './styles'; +import { Header } from '../Header'; import { InfoCard } from '../InfoCard'; +import { Page } from '../Page'; +import { getSignInProviders, useSignInProviders } from './providers'; +import { GridItem, useStyles } from './styles'; +import { IdentityProviders, SignInProviderConfig } from './types'; type MultiSignInPageProps = SignInPageProps & { providers: IdentityProviders; @@ -87,34 +87,63 @@ export const SingleSignInPage = ({ const authApi = useApi(provider.apiRef); const configApi = useApi(configApiRef); - const [retry, setRetry] = useState<{} | boolean | undefined>(auto); + const [autoShowPopup, setAutoShowPopup] = useState(auto ?? false); + // Defaults to true so that an initial check for existing user session is made + const [retry, setRetry] = useState<{} | boolean | undefined>(true); const [error, setError] = useState(); + // The SignIn component takes some time to decide whether the user is logged-in or not. + // showLoginPage is used to prevent a glitch-like experience where the sign-in page is + // displayed for a split second when the user is already logged-in. + const [showLoginPage, setShowLoginPage] = useState(false); + useEffect(() => { const login = async () => { - const identity = await authApi.getBackstageIdentity({ - instantPopup: true, - }); + try { + let identity; + // Do an initial check if any logged-in session exists + identity = await authApi.getBackstageIdentity({ + optional: true, + }); - const profile = await authApi.getProfile(); - onResult({ - userId: identity!.id, - profile: profile!, - getIdToken: () => { - return authApi.getBackstageIdentity().then(i => i!.idToken); - }, - signOut: async () => { - await authApi.signOut(); - }, - }); + // If no session exists, show the sign-in page + if (!identity && autoShowPopup) { + // Unless auto is set to true, this step should not happen. + // When user intentionally clicks the Sign In button, autoShowPopup is set to true + identity = await authApi.getBackstageIdentity({ + instantPopup: true, + }); + } + + if (!identity) { + setShowLoginPage(true); + return; + } + + const profile = await authApi.getProfile(); + onResult({ + userId: identity!.id, + profile: profile!, + getIdToken: () => { + return authApi.getBackstageIdentity().then(i => i!.idToken); + }, + signOut: async () => { + await authApi.signOut(); + }, + }); + } catch (err) { + // User closed the sign-in modal + setError(err); + setShowLoginPage(true); + } }; if (retry) { - login().catch(setError); + login(); } - }, [onResult, authApi, retry]); + }, [onResult, authApi, retry, autoShowPopup]); - return ( + return showLoginPage ? (
@@ -133,7 +162,10 @@ export const SingleSignInPage = ({ @@ -150,6 +182,8 @@ export const SingleSignInPage = ({ + ) : ( + ); };