diff --git a/packages/core-api/src/apis/definitions/IdentityApi.ts b/packages/core-api/src/apis/definitions/IdentityApi.ts index 5da9ed4814..dbc36ad967 100644 --- a/packages/core-api/src/apis/definitions/IdentityApi.ts +++ b/packages/core-api/src/apis/definitions/IdentityApi.ts @@ -35,7 +35,7 @@ export type IdentityApi = { * The ID token will be undefined if the signed in user does not have a verified * identity, such as a demo user or mocked user for e2e tests. */ - getIdToken(): string | undefined; + getIdToken(): Promise; // TODO: getProfile(): Promise - We want this to be async when added, but needs more work. diff --git a/packages/core-api/src/app/App.tsx b/packages/core-api/src/app/App.tsx index ec51814f85..a20a9b27f8 100644 --- a/packages/core-api/src/app/App.tsx +++ b/packages/core-api/src/app/App.tsx @@ -293,8 +293,6 @@ export class PrivateAppImpl implements BackstageApp { if (!SignInPageComponent) { this.identityApi.setSignInResult({ userId: 'guest', - idToken: undefined, - logout: async () => {}, }); return ( diff --git a/packages/core-api/src/app/AppIdentity.ts b/packages/core-api/src/app/AppIdentity.ts index 77de445a20..c38ece53df 100644 --- a/packages/core-api/src/app/AppIdentity.ts +++ b/packages/core-api/src/app/AppIdentity.ts @@ -24,7 +24,7 @@ import { SignInResult } from './types'; export class AppIdentity implements IdentityApi { private hasIdentity = false; private userId?: string; - private idToken?: string; + private idTokenFunc?: () => Promise; private logoutFunc?: () => Promise; getUserId(): string { @@ -36,13 +36,13 @@ export class AppIdentity implements IdentityApi { return this.userId!; } - getIdToken(): string | undefined { + async getIdToken(): Promise { if (!this.hasIdentity) { throw new Error( 'Tried to access IdentityApi idToken before app was loaded', ); } - return this.idToken; + return this.idTokenFunc?.(); } async logout(): Promise { @@ -64,7 +64,7 @@ export class AppIdentity implements IdentityApi { } this.hasIdentity = true; this.userId = result.userId; - this.idToken = result.idToken; + this.idTokenFunc = result.getIdToken; this.logoutFunc = result.logout; } } diff --git a/packages/core-api/src/app/types.ts b/packages/core-api/src/app/types.ts index a152ef9dfb..33b884fd58 100644 --- a/packages/core-api/src/app/types.ts +++ b/packages/core-api/src/app/types.ts @@ -32,9 +32,9 @@ export type SignInResult = { */ userId: string; /** - * ID token that will be returned by the IdentityApi + * Function used to retrieve an ID token for the signed in user. */ - idToken?: string; + getIdToken?: () => Promise; /** * Logout handler that will be called if the user requests a logout. */ diff --git a/packages/core/src/layout/SignInPage/customProvider.tsx b/packages/core/src/layout/SignInPage/customProvider.tsx index 8141175d8f..d24b054b16 100644 --- a/packages/core/src/layout/SignInPage/customProvider.tsx +++ b/packages/core/src/layout/SignInPage/customProvider.tsx @@ -28,7 +28,6 @@ import { import isEmpty from 'lodash/isEmpty'; import { InfoCard } from '../InfoCard/InfoCard'; import { ProviderComponent, ProviderLoader, SignInProvider } from './types'; -import { SignInResult } from '@backstage/core-api'; const ID_TOKEN_REGEX = /^[a-z0-9+/]+\.[a-z0-9+/]+\.[a-z0-9+/]+$/i; @@ -43,12 +42,24 @@ const useFormStyles = makeStyles(theme => ({ }, })); +type Data = { + userId: string; + idToken?: string; +}; + const Component: ProviderComponent = ({ onResult }) => { const classes = useFormStyles(); - const { register, handleSubmit, errors, formState } = useForm({ + const { register, handleSubmit, errors, formState } = useForm({ mode: 'onChange', }); + const handleResult = ({ userId, idToken }: Data) => { + onResult({ + userId, + getIdToken: idToken ? async () => idToken : undefined, + }); + }; + return ( @@ -58,7 +69,7 @@ const Component: ProviderComponent = ({ onResult }) => { This selection will not be stored. -
+ { const handleLogin = async () => { try { - const idToken = await googleAuthApi.getIdToken({ instantPopup: true }); + await googleAuthApi.getIdToken({ instantPopup: true }); const profile = await googleAuthApi.getProfile(); onResult({ userId: parseUserId(profile!), - idToken, + getIdToken: () => googleAuthApi.getIdToken(), logout: async () => { await googleAuthApi.logout(); }, @@ -69,14 +69,11 @@ const Component: ProviderComponent = ({ onResult }) => { const loader: ProviderLoader = async apis => { const googleAuthApi = apis.get(googleAuthApiRef)!; - const [idToken, profile] = await Promise.all([ - googleAuthApi.getIdToken({ optional: true }), - googleAuthApi.getProfile({ optional: true }), - ]); + const profile = await googleAuthApi.getProfile({ optional: true }); return { userId: parseUserId(profile!), - idToken, + getIdToken: () => googleAuthApi.getIdToken(), logout: async () => { await googleAuthApi.logout(); },