core: refactor SessionStateApi to SessionApi with sign-in/out
This commit is contained in:
@@ -46,9 +46,9 @@ export type IdentityApi = {
|
||||
// TODO: getProfile(): Promise<Profile> - We want this to be async when added, but needs more work.
|
||||
|
||||
/**
|
||||
* Log out the current user
|
||||
* Sign out the current user
|
||||
*/
|
||||
logout(): Promise<void>;
|
||||
signOut(): Promise<void>;
|
||||
};
|
||||
|
||||
export const identityApiRef = createApiRef<IdentityApi>({
|
||||
|
||||
@@ -90,11 +90,6 @@ export type OAuthApi = {
|
||||
scope?: OAuthScope,
|
||||
options?: AuthRequestOptions,
|
||||
): Promise<string>;
|
||||
|
||||
/**
|
||||
* Log out the user's session. This will reload the page.
|
||||
*/
|
||||
logout(): Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -114,11 +109,6 @@ export type OpenIdConnectApi = {
|
||||
* The returned promise can be rejected, but only if the user rejects the login request.
|
||||
*/
|
||||
getIdToken(options?: AuthRequestOptions): Promise<string>;
|
||||
|
||||
/**
|
||||
* Log out the user's session. This will reload the page.
|
||||
*/
|
||||
logout(): Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -187,7 +177,7 @@ export type ProfileInfo = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Session state values passed to subscribers of the SessionStateApi.
|
||||
* Session state values passed to subscribers of the SessionApi.
|
||||
*/
|
||||
export enum SessionState {
|
||||
SignedIn = 'SignedIn',
|
||||
@@ -195,10 +185,22 @@ export enum SessionState {
|
||||
}
|
||||
|
||||
/**
|
||||
* This API provides access to an sessionState$ observable which provides an update when the
|
||||
* user performs a sign in or sign out from an auth provider.
|
||||
* The SessionApi provides basic controls for any auth provider that is tied to a persistent session.
|
||||
*/
|
||||
export type SessionStateApi = {
|
||||
export type SessionApi = {
|
||||
/**
|
||||
* Sign in with a minimum set of permissions.
|
||||
*/
|
||||
signIn(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Sign out from the current session. This will reload the page.
|
||||
*/
|
||||
signOut(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Observe the current state of the auth session. Emits the current state on subscription.
|
||||
*/
|
||||
sessionState$(): Observable<SessionState>;
|
||||
};
|
||||
|
||||
@@ -215,7 +217,7 @@ export const googleAuthApiRef = createApiRef<
|
||||
OpenIdConnectApi &
|
||||
ProfileInfoApi &
|
||||
BackstageIdentityApi &
|
||||
SessionStateApi
|
||||
SessionApi
|
||||
>({
|
||||
id: 'core.auth.google',
|
||||
description: 'Provides authentication towards Google APIs and identities',
|
||||
@@ -228,7 +230,7 @@ export const googleAuthApiRef = createApiRef<
|
||||
* for a full list of supported scopes.
|
||||
*/
|
||||
export const githubAuthApiRef = createApiRef<
|
||||
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi
|
||||
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
|
||||
>({
|
||||
id: 'core.auth.github',
|
||||
description: 'Provides authentication towards GitHub APIs',
|
||||
@@ -245,7 +247,7 @@ export const oktaAuthApiRef = createApiRef<
|
||||
OpenIdConnectApi &
|
||||
ProfileInfoApi &
|
||||
BackstageIdentityApi &
|
||||
SessionStateApi
|
||||
SessionApi
|
||||
>({
|
||||
id: 'core.auth.okta',
|
||||
description: 'Provides authentication towards Okta APIs',
|
||||
@@ -258,7 +260,7 @@ export const oktaAuthApiRef = createApiRef<
|
||||
* for a full list of supported scopes.
|
||||
*/
|
||||
export const gitlabAuthApiRef = createApiRef<
|
||||
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi
|
||||
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
|
||||
>({
|
||||
id: 'core.auth.gitlab',
|
||||
description: 'Provides authentication towards GitLab APIs',
|
||||
@@ -271,7 +273,7 @@ export const gitlabAuthApiRef = createApiRef<
|
||||
* for a full list of supported scopes.
|
||||
*/
|
||||
export const auth0AuthApiRef = createApiRef<
|
||||
OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi
|
||||
OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
|
||||
>({
|
||||
id: 'core.auth.auth0',
|
||||
description: 'Provides authentication towards Auth0 APIs',
|
||||
@@ -289,7 +291,7 @@ export const microsoftAuthApiRef = createApiRef<
|
||||
OpenIdConnectApi &
|
||||
ProfileInfoApi &
|
||||
BackstageIdentityApi &
|
||||
SessionStateApi
|
||||
SessionApi
|
||||
>({
|
||||
id: 'core.auth.microsoft',
|
||||
description: 'Provides authentication towards Microsoft APIs and identities',
|
||||
@@ -302,8 +304,8 @@ export const oauth2ApiRef = createApiRef<
|
||||
OAuthApi &
|
||||
OpenIdConnectApi &
|
||||
ProfileInfoApi &
|
||||
SessionStateApi &
|
||||
BackstageIdentityApi
|
||||
BackstageIdentityApi &
|
||||
SessionApi
|
||||
>({
|
||||
id: 'core.auth.oauth2',
|
||||
description: 'Example of how to use oauth2 custom provider',
|
||||
|
||||
@@ -19,7 +19,7 @@ import { DefaultAuthConnector } from '../../../../lib/AuthConnector';
|
||||
import { GithubSession } from './types';
|
||||
import {
|
||||
OAuthApi,
|
||||
SessionStateApi,
|
||||
SessionApi,
|
||||
SessionState,
|
||||
ProfileInfo,
|
||||
BackstageIdentity,
|
||||
@@ -61,7 +61,7 @@ const DEFAULT_PROVIDER = {
|
||||
icon: GithubIcon,
|
||||
};
|
||||
|
||||
class GithubAuth implements OAuthApi, SessionStateApi {
|
||||
class GithubAuth implements OAuthApi, SessionApi {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
@@ -102,12 +102,20 @@ class GithubAuth implements OAuthApi, SessionStateApi {
|
||||
return new GithubAuth(authSessionStore);
|
||||
}
|
||||
|
||||
constructor(private readonly sessionManager: SessionManager<GithubSession>) {}
|
||||
|
||||
async signIn() {
|
||||
await this.getAccessToken();
|
||||
}
|
||||
|
||||
async signOut() {
|
||||
await this.sessionManager.removeSession();
|
||||
}
|
||||
|
||||
sessionState$(): Observable<SessionState> {
|
||||
return this.sessionManager.sessionState$();
|
||||
}
|
||||
|
||||
constructor(private readonly sessionManager: SessionManager<GithubSession>) {}
|
||||
|
||||
async getAccessToken(scope?: string, options?: AuthRequestOptions) {
|
||||
const session = await this.sessionManager.getSession({
|
||||
...options,
|
||||
@@ -128,10 +136,6 @@ class GithubAuth implements OAuthApi, SessionStateApi {
|
||||
return session?.profile;
|
||||
}
|
||||
|
||||
async logout() {
|
||||
await this.sessionManager.removeSession();
|
||||
}
|
||||
|
||||
static normalizeScope(scope?: string): Set<string> {
|
||||
if (!scope) {
|
||||
return new Set();
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
ProfileInfo,
|
||||
ProfileInfoApi,
|
||||
SessionState,
|
||||
SessionStateApi,
|
||||
SessionApi,
|
||||
BackstageIdentityApi,
|
||||
} from '../../../definitions/auth';
|
||||
import { OAuth2Session } from './types';
|
||||
@@ -75,7 +75,7 @@ class OAuth2
|
||||
OpenIdConnectApi,
|
||||
ProfileInfoApi,
|
||||
BackstageIdentityApi,
|
||||
SessionStateApi {
|
||||
SessionApi {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
@@ -129,6 +129,14 @@ class OAuth2
|
||||
this.scopeTransform = options.scopeTransform;
|
||||
}
|
||||
|
||||
async signIn() {
|
||||
await this.getAccessToken();
|
||||
}
|
||||
|
||||
async signOut() {
|
||||
await this.sessionManager.removeSession();
|
||||
}
|
||||
|
||||
sessionState$(): Observable<SessionState> {
|
||||
return this.sessionManager.sessionState$();
|
||||
}
|
||||
@@ -150,10 +158,6 @@ class OAuth2
|
||||
return session?.providerInfo.idToken ?? '';
|
||||
}
|
||||
|
||||
async logout() {
|
||||
await this.sessionManager.removeSession();
|
||||
}
|
||||
|
||||
async getBackstageIdentity(
|
||||
options: AuthRequestOptions = {},
|
||||
): Promise<BackstageIdentity | undefined> {
|
||||
|
||||
@@ -26,7 +26,7 @@ export class AppIdentity implements IdentityApi {
|
||||
private userId?: string;
|
||||
private profile?: ProfileInfo;
|
||||
private idTokenFunc?: () => Promise<string>;
|
||||
private logoutFunc?: () => Promise<void>;
|
||||
private signOutFunc?: () => Promise<void>;
|
||||
|
||||
getUserId(): string {
|
||||
if (!this.hasIdentity) {
|
||||
@@ -55,13 +55,13 @@ export class AppIdentity implements IdentityApi {
|
||||
return this.idTokenFunc?.();
|
||||
}
|
||||
|
||||
async logout(): Promise<void> {
|
||||
async signOut(): Promise<void> {
|
||||
if (!this.hasIdentity) {
|
||||
throw new Error(
|
||||
'Tried to access IdentityApi logoutFunc before app was loaded',
|
||||
'Tried to access IdentityApi signOutFunc before app was loaded',
|
||||
);
|
||||
}
|
||||
await this.logoutFunc?.();
|
||||
await this.signOutFunc?.();
|
||||
location.reload();
|
||||
}
|
||||
|
||||
@@ -80,6 +80,6 @@ export class AppIdentity implements IdentityApi {
|
||||
this.userId = result.userId;
|
||||
this.profile = result.profile;
|
||||
this.idTokenFunc = result.getIdToken;
|
||||
this.logoutFunc = result.logout;
|
||||
this.signOutFunc = result.signOut;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,10 +38,11 @@ export type SignInResult = {
|
||||
* Function used to retrieve an ID token for the signed in user.
|
||||
*/
|
||||
getIdToken?: () => Promise<string>;
|
||||
|
||||
/**
|
||||
* Logout handler that will be called if the user requests a logout.
|
||||
* Sign out handler that will be called if the user requests to sign out.
|
||||
*/
|
||||
logout?: () => Promise<void>;
|
||||
signOut?: () => Promise<void>;
|
||||
};
|
||||
|
||||
export type SignInPageProps = {
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
} from '@backstage/core-api';
|
||||
import Star from '@material-ui/icons/Star';
|
||||
import React from 'react';
|
||||
import { OAuthProviderSettings, OIDCProviderSettings } from './Settings';
|
||||
import { ProviderSettingsItem } from './Settings';
|
||||
|
||||
export const DefaultProviderSettings = () => {
|
||||
const configApi = useApi(configApiRef);
|
||||
@@ -35,42 +35,42 @@ export const DefaultProviderSettings = () => {
|
||||
return (
|
||||
<>
|
||||
{providers.includes('google') && (
|
||||
<OIDCProviderSettings
|
||||
<ProviderSettingsItem
|
||||
title="Google"
|
||||
apiRef={googleAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
)}
|
||||
{providers.includes('microsoft') && (
|
||||
<OIDCProviderSettings
|
||||
<ProviderSettingsItem
|
||||
title="Microsoft"
|
||||
apiRef={microsoftAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
)}
|
||||
{providers.includes('github') && (
|
||||
<OAuthProviderSettings
|
||||
<ProviderSettingsItem
|
||||
title="Github"
|
||||
apiRef={githubAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
)}
|
||||
{providers.includes('gitlab') && (
|
||||
<OAuthProviderSettings
|
||||
<ProviderSettingsItem
|
||||
title="Gitlab"
|
||||
apiRef={gitlabAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
)}
|
||||
{providers.includes('okta') && (
|
||||
<OIDCProviderSettings
|
||||
<ProviderSettingsItem
|
||||
title="Okta"
|
||||
apiRef={oktaAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
)}
|
||||
{providers.includes('oauth2') && (
|
||||
<OIDCProviderSettings
|
||||
<ProviderSettingsItem
|
||||
title="YourOrg"
|
||||
apiRef={oauth2ApiRef}
|
||||
icon={Star}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ApiRef,
|
||||
OAuthApi,
|
||||
SessionStateApi,
|
||||
useApi,
|
||||
Subscription,
|
||||
IconComponent,
|
||||
SessionState,
|
||||
} from '@backstage/core-api';
|
||||
import React, { FC, useState, useEffect } from 'react';
|
||||
import { ProviderSettingsItem } from './ProviderSettingsItem';
|
||||
|
||||
type OAuthProviderSidebarProps = {
|
||||
title: string;
|
||||
icon: IconComponent;
|
||||
apiRef: ApiRef<OAuthApi & SessionStateApi>;
|
||||
};
|
||||
|
||||
export const OAuthProviderSettings: FC<OAuthProviderSidebarProps> = ({
|
||||
title,
|
||||
icon,
|
||||
apiRef,
|
||||
}) => {
|
||||
const api = useApi(apiRef);
|
||||
const [signedIn, setSignedIn] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let didCancel = false;
|
||||
|
||||
const checkSession = async () => {
|
||||
const session = await api.getAccessToken('', { optional: true });
|
||||
if (!didCancel) {
|
||||
setSignedIn(!!session);
|
||||
}
|
||||
};
|
||||
let subscription: Subscription;
|
||||
const observeSession = () => {
|
||||
subscription = api
|
||||
.sessionState$()
|
||||
.subscribe((sessionState: SessionState) => {
|
||||
if (!didCancel) {
|
||||
setSignedIn(sessionState === SessionState.SignedIn);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
checkSession();
|
||||
observeSession();
|
||||
return () => {
|
||||
didCancel = true;
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}, [api]);
|
||||
|
||||
return (
|
||||
<ProviderSettingsItem
|
||||
title={title}
|
||||
icon={icon}
|
||||
signedIn={signedIn}
|
||||
api={api}
|
||||
signInHandler={() => api.getAccessToken()}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ApiRef,
|
||||
OpenIdConnectApi,
|
||||
SessionStateApi,
|
||||
useApi,
|
||||
Subscription,
|
||||
IconComponent,
|
||||
SessionState,
|
||||
} from '@backstage/core-api';
|
||||
import React, { FC, useState, useEffect } from 'react';
|
||||
import { ProviderSettingsItem } from './ProviderSettingsItem';
|
||||
|
||||
export type OIDCProviderSidebarProps = {
|
||||
title: string;
|
||||
icon: IconComponent;
|
||||
apiRef: ApiRef<OpenIdConnectApi & SessionStateApi>;
|
||||
};
|
||||
|
||||
export const OIDCProviderSettings: FC<OIDCProviderSidebarProps> = ({
|
||||
title,
|
||||
icon,
|
||||
apiRef,
|
||||
}) => {
|
||||
const api = useApi(apiRef);
|
||||
const [signedIn, setSignedIn] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let didCancel = false;
|
||||
|
||||
const checkSession = async () => {
|
||||
const session = await api.getIdToken({ optional: true });
|
||||
if (!didCancel) {
|
||||
setSignedIn(!!session);
|
||||
}
|
||||
};
|
||||
|
||||
let subscription: Subscription;
|
||||
const observeSession = () => {
|
||||
subscription = api
|
||||
.sessionState$()
|
||||
.subscribe((sessionState: SessionState) => {
|
||||
if (!didCancel) {
|
||||
setSignedIn(sessionState === SessionState.SignedIn);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
checkSession();
|
||||
observeSession();
|
||||
return () => {
|
||||
didCancel = true;
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}, [api]);
|
||||
|
||||
return (
|
||||
<ProviderSettingsItem
|
||||
title={title}
|
||||
icon={icon}
|
||||
signedIn={signedIn}
|
||||
api={api}
|
||||
signInHandler={() => api.getIdToken()}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -14,8 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { IconComponent, OAuthApi, OpenIdConnectApi } from '@backstage/core-api';
|
||||
import React, { FC, useState, useEffect } from 'react';
|
||||
import {
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
@@ -25,42 +24,67 @@ import {
|
||||
} from '@material-ui/core';
|
||||
import PowerButton from '@material-ui/icons/PowerSettingsNew';
|
||||
import { ToggleButton } from '@material-ui/lab';
|
||||
import {
|
||||
ApiRef,
|
||||
SessionApi,
|
||||
useApi,
|
||||
IconComponent,
|
||||
SessionState,
|
||||
} from '@backstage/core-api';
|
||||
|
||||
type Props = {
|
||||
type OAuthProviderSidebarProps = {
|
||||
title: string;
|
||||
icon: IconComponent;
|
||||
signedIn: boolean;
|
||||
api: OAuthApi | OpenIdConnectApi;
|
||||
signInHandler: Function;
|
||||
apiRef: ApiRef<SessionApi>;
|
||||
};
|
||||
|
||||
export const ProviderSettingsItem = ({
|
||||
export const ProviderSettingsItem: FC<OAuthProviderSidebarProps> = ({
|
||||
title,
|
||||
icon: Icon,
|
||||
signedIn,
|
||||
api,
|
||||
signInHandler,
|
||||
}: Props) => (
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<Icon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={title} />
|
||||
<ListItemSecondaryAction>
|
||||
<ToggleButton
|
||||
size="small"
|
||||
value={title}
|
||||
selected={signedIn}
|
||||
onChange={() => (signedIn ? api.logout() : signInHandler())}
|
||||
>
|
||||
<Tooltip
|
||||
placement="top"
|
||||
arrow
|
||||
title={signedIn ? `Sign out from ${title}` : `Sign in to ${title}`}
|
||||
apiRef,
|
||||
}) => {
|
||||
const api = useApi(apiRef);
|
||||
const [signedIn, setSignedIn] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let didCancel = false;
|
||||
|
||||
const subscription = api
|
||||
.sessionState$()
|
||||
.subscribe((sessionState: SessionState) => {
|
||||
if (!didCancel) {
|
||||
setSignedIn(sessionState === SessionState.SignedIn);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
didCancel = true;
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}, [api]);
|
||||
|
||||
return (
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<Icon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={title} />
|
||||
<ListItemSecondaryAction>
|
||||
<ToggleButton
|
||||
size="small"
|
||||
value={title}
|
||||
selected={signedIn}
|
||||
onChange={() => (signedIn ? api.signOut() : api.signIn())}
|
||||
>
|
||||
<PowerButton />
|
||||
</Tooltip>
|
||||
</ToggleButton>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
);
|
||||
<Tooltip
|
||||
placement="top"
|
||||
arrow
|
||||
title={signedIn ? `Sign out from ${title}` : `Sign in to ${title}`}
|
||||
>
|
||||
<PowerButton />
|
||||
</Tooltip>
|
||||
</ToggleButton>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ export const UserSettingsMenu = () => {
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
|
||||
<MenuItem onClick={() => identityApi.logout()}>
|
||||
<MenuItem onClick={() => identityApi.signOut()}>
|
||||
<ListItemIcon>
|
||||
<SignOutIcon />
|
||||
</ListItemIcon>
|
||||
|
||||
@@ -15,6 +15,4 @@
|
||||
*/
|
||||
|
||||
export { ProviderSettingsItem } from './ProviderSettingsItem';
|
||||
export { OAuthProviderSettings } from './OAuthProviderSettings';
|
||||
export { OIDCProviderSettings } from './OIDCProviderSettings';
|
||||
export { SidebarUserSettings } from './UserSettings';
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
SidebarSearchField,
|
||||
SidebarSpace,
|
||||
SidebarUserSettings,
|
||||
OAuthProviderSettings,
|
||||
ProviderSettingsItem,
|
||||
} from '.';
|
||||
import HomeOutlinedIcon from '@material-ui/icons/HomeOutlined';
|
||||
import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';
|
||||
@@ -60,7 +60,7 @@ export const SampleSidebar = () => (
|
||||
<SidebarDivider />
|
||||
<SidebarUserSettings
|
||||
providerSettings={
|
||||
<OAuthProviderSettings
|
||||
<ProviderSettingsItem
|
||||
title="Github"
|
||||
apiRef={githubAuthApiRef}
|
||||
icon={Star}
|
||||
|
||||
@@ -37,8 +37,8 @@ const Component: ProviderComponent = ({ onResult }) => {
|
||||
profile: profile!,
|
||||
getIdToken: () =>
|
||||
auth0AuthApi.getBackstageIdentity().then(i => i!.idToken),
|
||||
logout: async () => {
|
||||
await auth0AuthApi.logout();
|
||||
signOut: async () => {
|
||||
await auth0AuthApi.signOut();
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -79,8 +79,8 @@ const loader: ProviderLoader = async apis => {
|
||||
userId: identity.id,
|
||||
profile: profile!,
|
||||
getIdToken: () => auth0AuthApi.getBackstageIdentity().then(i => i!.idToken),
|
||||
logout: async () => {
|
||||
await auth0AuthApi.logout();
|
||||
signOut: async () => {
|
||||
await auth0AuthApi.signOut();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -44,8 +44,8 @@ const Component: ProviderComponent = ({ config, onResult }) => {
|
||||
getIdToken: () => {
|
||||
return authApi.getBackstageIdentity().then(i => i!.idToken);
|
||||
},
|
||||
logout: async () => {
|
||||
await authApi.logout();
|
||||
signOut: async () => {
|
||||
await authApi.signOut();
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -87,8 +87,8 @@ const loader: ProviderLoader = async (apis, apiRef) => {
|
||||
userId: identity.id,
|
||||
profile: profile!,
|
||||
getIdToken: () => authApi.getBackstageIdentity().then(i => i!.idToken),
|
||||
logout: async () => {
|
||||
await authApi.logout();
|
||||
signOut: async () => {
|
||||
await authApi.signOut();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -83,14 +83,14 @@ export const useSignInProviders = (
|
||||
const apiHolder = useApiHolder();
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// This decorates the result with logout logic from this hook
|
||||
// This decorates the result with sign out logic from this hook
|
||||
const handleWrappedResult = useCallback(
|
||||
(result: SignInResult) => {
|
||||
onResult({
|
||||
...result,
|
||||
logout: async () => {
|
||||
signOut: async () => {
|
||||
localStorage.removeItem(PROVIDER_STORAGE_KEY);
|
||||
await result.logout?.();
|
||||
await result.signOut?.();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -20,19 +20,16 @@ import {
|
||||
SignInResult,
|
||||
ApiHolder,
|
||||
ApiRef,
|
||||
OAuthApi,
|
||||
ProfileInfoApi,
|
||||
BackstageIdentityApi,
|
||||
SessionStateApi,
|
||||
SessionApi,
|
||||
} from '@backstage/core-api';
|
||||
|
||||
export type SignInConfig = {
|
||||
id: string;
|
||||
title: string;
|
||||
message: string;
|
||||
apiRef: ApiRef<
|
||||
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi
|
||||
>;
|
||||
apiRef: ApiRef<ProfileInfoApi & BackstageIdentityApi & SessionApi>;
|
||||
};
|
||||
|
||||
export type IdentityProviders = ('guest' | 'custom' | SignInConfig)[];
|
||||
@@ -43,9 +40,7 @@ export type ProviderComponent = ComponentType<
|
||||
|
||||
export type ProviderLoader = (
|
||||
apis: ApiHolder,
|
||||
apiRef: ApiRef<
|
||||
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi
|
||||
>,
|
||||
apiRef: ApiRef<ProfileInfoApi & BackstageIdentityApi & SessionApi>,
|
||||
) => Promise<SignInResult | undefined>;
|
||||
|
||||
export type SignInProvider = {
|
||||
|
||||
@@ -36,7 +36,7 @@ builder.add(identityApiRef, {
|
||||
getUserId: () => 'guest',
|
||||
getProfile: () => ({ email: 'guest@example.com' }),
|
||||
getIdToken: () => undefined,
|
||||
logout: async () => {},
|
||||
signOut: async () => {},
|
||||
});
|
||||
|
||||
const oauthRequestApi = builder.add(
|
||||
|
||||
Reference in New Issue
Block a user