core: removed deprecated IdentityApi methods

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2022-01-04 21:56:26 +01:00
parent 9c5cd63243
commit ceebe25391
12 changed files with 117 additions and 83 deletions
+24
View File
@@ -0,0 +1,24 @@
---
'@backstage/core-plugin-api': minor
---
Removed deprecated `IdentityApi` methods: `getUserId`, `getIdToken`, and `getProfile`.
Existing usage of `getUserId` can be replaced by `getBackstageIdentity`, more precisely the equivalent of the previous `userId` can be retrieved like this:
```ts
import { parseEntityRef } from '@backstage/catalog-model';
const identity = await identityApi.getBackstageIdentity();
const { name: userId } = parseEntityRef(identity.userEntityRef);
```
Note that it is recommended to consume the entire `userEntityRef` rather than parsing out just the name, in order to support namespaces.
Existing usage of `getIdToken` can be replaced by `getCredentials`, like this:
```ts
const { token } = await identityApi.getCredentials();
```
And existing usage of `getProfile` is replaced by `getProfileInfo`, which returns the same profile object, but is now async.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/core-app-api': minor
'@backstage/core-plugin-api': minor
---
Removed deprecated `SignInResult` type, which was replaced with the new `onSignInSuccess` callback.
-8
View File
@@ -563,14 +563,6 @@ export type SignInPageProps = {
onSignInSuccess(identityApi: IdentityApi): void;
};
// @public @deprecated
export type SignInResult = {
userId: string;
profile: ProfileInfo;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
};
// @public
export class UnhandledErrorForwarder {
static forward(errorApi: ErrorApi, errorContext: ErrorApiErrorContext): void;
@@ -26,15 +26,30 @@ function mkError(thing: string) {
);
}
function logDeprecation(thing: string) {
// eslint-disable-next-line no-console
console.warn(
`WARNING: Call to ${thing} is deprecated and will break in the future`,
);
}
// We use this for a period of backwards compatibility. It is a hidden
// compatibility that will allow old plugins to continue working for a limited time.
type CompatibilityIdentityApi = IdentityApi & {
getUserId?(): string;
getIdToken?(): Promise<string | undefined>;
getProfile?(): ProfileInfo;
};
/**
* Implementation of the connection between the App-wide IdentityApi
* and sign-in page.
*/
export class AppIdentityProxy implements IdentityApi {
private target?: IdentityApi;
private target?: CompatibilityIdentityApi;
// This is called by the app manager once the sign-in page provides us with an implementation
setTarget(identityApi: IdentityApi) {
setTarget(identityApi: CompatibilityIdentityApi) {
this.target = identityApi;
}
@@ -42,6 +57,10 @@ export class AppIdentityProxy implements IdentityApi {
if (!this.target) {
throw mkError('getUserId');
}
if (!this.target.getUserId) {
throw new Error('IdentityApi does not implement getUserId');
}
logDeprecation('getUserId');
return this.target.getUserId();
}
@@ -49,6 +68,10 @@ export class AppIdentityProxy implements IdentityApi {
if (!this.target) {
throw mkError('getProfile');
}
if (!this.target.getProfile) {
throw new Error('IdentityApi does not implement getProfile');
}
logDeprecation('getProfile');
return this.target.getProfile();
}
@@ -77,6 +100,10 @@ export class AppIdentityProxy implements IdentityApi {
if (!this.target) {
throw mkError('getIdToken');
}
if (!this.target.getIdToken) {
throw new Error('IdentityApi does not implement getIdToken');
}
logDeprecation('getIdToken');
return this.target.getIdToken();
}
-26
View File
@@ -18,7 +18,6 @@ import { ComponentType } from 'react';
import {
AnyApiFactory,
AppTheme,
ProfileInfo,
IconComponent,
BackstagePlugin,
RouteRef,
@@ -38,31 +37,6 @@ export type BootErrorPageProps = {
error: Error;
};
/**
* The outcome of signing in on the sign-in page.
*
* @public
* @deprecated replaced by passing the {@link @backstage/core-plugin-api#IdentityApi} to the {@link SignInPageProps.onSignInSuccess} instead.
*/
export type SignInResult = {
/**
* User ID that will be returned by the IdentityApi
*/
userId: string;
profile: ProfileInfo;
/**
* Function used to retrieve an ID token for the signed in user.
*/
getIdToken?: () => Promise<string>;
/**
* Sign out handler that will be called if the user requests to sign out.
*/
signOut?: () => Promise<void>;
};
/**
* Props for the `SignInPage` component of {@link AppComponents}.
*
+6 -2
View File
@@ -38,7 +38,6 @@ import { ReactElement } from 'react';
import { ReactNode } from 'react';
import { SessionApi } from '@backstage/core-plugin-api';
import { SignInPageProps } from '@backstage/core-plugin-api';
import { SignInResult } from '@backstage/core-plugin-api';
import { SparklinesLineProps } from 'react-sparklines';
import { SparklinesProps } from 'react-sparklines';
import { StyledComponentProps } from '@material-ui/core/styles';
@@ -2395,7 +2394,12 @@ export class UserIdentity implements IdentityApi {
profile?: ProfileInfo;
}): IdentityApi;
static createGuest(): IdentityApi;
static fromLegacy(result: SignInResult): IdentityApi;
static fromLegacy(result: {
userId: string;
profile: ProfileInfo;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
}): IdentityApi;
// (undocumented)
getBackstageIdentity(): Promise<BackstageUserIdentity>;
// (undocumented)
@@ -20,30 +20,46 @@ import {
ProfileInfo,
} from '@backstage/core-plugin-api';
// Similar to the AppIdentityApi we provide backwards compatibility for a limited time
type CompatibilityIdentityApi = IdentityApi & {
getUserId?(): string;
getIdToken?(): Promise<string | undefined>;
getProfile?(): ProfileInfo;
};
export class IdentityApiSignOutProxy implements IdentityApi {
private constructor(
private readonly config: {
identityApi: IdentityApi;
identityApi: CompatibilityIdentityApi;
signOut: IdentityApi['signOut'];
},
) {}
static from(config: {
identityApi: IdentityApi;
identityApi: CompatibilityIdentityApi;
signOut: IdentityApi['signOut'];
}): IdentityApi {
return new IdentityApiSignOutProxy(config);
}
getUserId(): string {
if (!this.config.identityApi.getUserId) {
throw new Error(`SignOutProxy IdentityApi.getUserId is not implemented`);
}
return this.config.identityApi.getUserId();
}
getIdToken(): Promise<string | undefined> {
if (!this.config.identityApi.getIdToken) {
throw new Error(`SignOutProxy IdentityApi.getIdToken is not implemented`);
}
return this.config.identityApi.getIdToken();
}
getProfile(): ProfileInfo {
if (!this.config.identityApi.getProfile) {
throw new Error(`SignOutProxy IdentityApi.getProfile is not implemented`);
}
return this.config.identityApi.getProfile();
}
@@ -18,7 +18,6 @@ import {
IdentityApi,
ProfileInfo,
BackstageUserIdentity,
SignInResult,
} from '@backstage/core-plugin-api';
function parseJwtPayload(token: string) {
@@ -26,14 +25,22 @@ function parseJwtPayload(token: string) {
return JSON.parse(atob(payload));
}
type LegacySignInResult = {
userId: string;
profile: ProfileInfo;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
};
/** @internal */
export class LegacyUserIdentity implements IdentityApi {
private constructor(private readonly result: SignInResult) {}
private constructor(private readonly result: LegacySignInResult) {}
getUserId(): string {
return this.result.userId;
}
static fromResult(result: SignInResult): LegacyUserIdentity {
static fromResult(result: LegacySignInResult): LegacyUserIdentity {
return new LegacyUserIdentity(result);
}
@@ -21,12 +21,17 @@ import {
BackstageUserIdentity,
BackstageIdentityApi,
SessionApi,
SignInResult,
} from '@backstage/core-plugin-api';
import { GuestUserIdentity } from './GuestUserIdentity';
import { LegacyUserIdentity } from './LegacyUserIdentity';
// TODO(Rugvip): This and the other IdentityApi implementations still implement
// the old removed methods. This is to allow for backwards compatibility
// with old plugins that still consume this API. We will leave these in
// place as a hidden compatibility for a couple of months.
// The AppIdentityProxy warns in case any of these methods are called.
/**
* An implementation of the IdentityApi that is constructed using
* various backstage user identity representations.
@@ -49,7 +54,24 @@ export class UserIdentity implements IdentityApi {
*
* @public
*/
static fromLegacy(result: SignInResult): IdentityApi {
static fromLegacy(result: {
/**
* User ID that will be returned by the IdentityApi
*/
userId: string;
profile: ProfileInfo;
/**
* Function used to retrieve an ID token for the signed in user.
*/
getIdToken?: () => Promise<string>;
/**
* Sign out handler that will be called if the user requests to sign out.
*/
signOut?: () => Promise<void>;
}): IdentityApi {
return LegacyUserIdentity.fromResult(result);
}
-12
View File
@@ -12,7 +12,6 @@ import { IconComponent as IconComponent_2 } from '@backstage/core-plugin-api';
import { IdentityApi as IdentityApi_2 } from '@backstage/core-plugin-api';
import { JsonValue } from '@backstage/types';
import { Observable } from '@backstage/types';
import { ProfileInfo as ProfileInfo_2 } from '@backstage/core-plugin-api';
import { default as React_2 } from 'react';
import { ReactElement } from 'react';
import { ReactNode } from 'react';
@@ -512,9 +511,6 @@ export type IconComponent = ComponentType<{
// @public
export type IdentityApi = {
getUserId(): string;
getIdToken(): Promise<string | undefined>;
getProfile(): ProfileInfo;
getProfileInfo(): Promise<ProfileInfo>;
getBackstageIdentity(): Promise<BackstageUserIdentity>;
getCredentials(): Promise<{
@@ -732,14 +728,6 @@ export type SignInPageProps = {
onSignInSuccess(identityApi: IdentityApi_2): void;
};
// @public @deprecated
export type SignInResult = {
userId: string;
profile: ProfileInfo_2;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
};
// @public
export interface StorageApi {
forBucket(name: string): StorageApi;
@@ -22,31 +22,6 @@ import { BackstageUserIdentity, ProfileInfo } from './auth';
* @public
*/
export type IdentityApi = {
/**
* The ID of the signed in user. This ID is not meant to be presented to the user, but used
* as an opaque string to pass on to backends or use in frontend logic.
*
* @deprecated use {@link IdentityApi.getBackstageIdentity} instead.
*/
getUserId(): string;
/**
* An OpenID Connect ID Token which proves the identity of the signed in user.
*
* 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.
*
* @deprecated use {@link IdentityApi.getCredentials} instead.
*/
getIdToken(): Promise<string | undefined>;
/**
* The profile of the signed in user.
*
* @deprecated use {@link IdentityApi.getProfileInfo} instead.
*/
getProfile(): ProfileInfo;
/**
* The profile of the signed in user.
*/
@@ -20,7 +20,6 @@
// eslint-disable-next-line no-restricted-imports
export type {
BootErrorPageProps,
SignInResult,
SignInPageProps,
ErrorBoundaryFallbackProps,
AppComponents,