@backstage/core-app-api 1.7.0-next.1 → 1.7.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @backstage/core-app-api
2
2
 
3
+ ## 1.7.0-next.3
4
+
5
+ ### Minor Changes
6
+
7
+ - c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when
8
+ refreshing a session. The `DefaultAuthConnector` implementation passes the
9
+ `scope` query parameter to the auth-backend plugin appropriately. The
10
+ `RefreshingAuthSessionManager` passes any scopes in its `GetSessionRequest`
11
+ appropriately.
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+ - @backstage/config@1.0.7
17
+ - @backstage/core-plugin-api@1.5.1-next.1
18
+ - @backstage/types@1.0.2
19
+ - @backstage/version-bridge@1.0.4-next.0
20
+
21
+ ## 1.7.0-next.2
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies
26
+ - @backstage/core-plugin-api@1.5.1-next.1
27
+ - @backstage/config@1.0.7
28
+ - @backstage/types@1.0.2
29
+ - @backstage/version-bridge@1.0.4-next.0
30
+
3
31
  ## 1.7.0-next.1
4
32
 
5
33
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ReactNode, PropsWithChildren, ComponentType } from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
4
  import { ApiHolder, ApiRef, ApiFactory, AnyApiRef, OAuthRequestApi, DiscoveryApi, AuthProviderInfo, ConfigApi, githubAuthApiRef, gitlabAuthApiRef, googleAuthApiRef, OAuthApi, OpenIdConnectApi, ProfileInfoApi, BackstageIdentityApi, SessionApi, SessionState, AuthRequestOptions, BackstageIdentityResponse, ProfileInfo, oktaAuthApiRef, microsoftAuthApiRef, oneloginAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, atlassianAuthApiRef, AlertApi, AlertMessage, AnalyticsApi, AnalyticsEvent, AppThemeApi, AppTheme, ErrorApi, ErrorApiError, ErrorApiErrorContext, FeatureFlagsApi, FeatureFlag, FeatureFlagsSaveOptions, FetchApi, IdentityApi, OAuthRequesterOptions, OAuthRequester, PendingOAuthRequest, StorageApi, StorageValueSnapshot, BackstagePlugin, IconComponent, ExternalRouteRef, AnyApiFactory, RouteRef, SubRouteRef } from '@backstage/core-plugin-api';
4
5
  import * as _backstage_types from '@backstage/types';
5
6
  import { Observable, JsonValue } from '@backstage/types';
@@ -10,7 +11,7 @@ export { ConfigReader } from '@backstage/config';
10
11
  * Prop types for the ApiProvider component.
11
12
  * @public
12
13
  */
13
- declare type ApiProviderProps = {
14
+ type ApiProviderProps = {
14
15
  apis: ApiHolder;
15
16
  children: ReactNode;
16
17
  };
@@ -23,9 +24,9 @@ declare type ApiProviderProps = {
23
24
  declare const ApiProvider: {
24
25
  (props: PropsWithChildren<ApiProviderProps>): JSX.Element;
25
26
  propTypes: {
26
- apis: PropTypes.Validator<PropTypes.InferProps<{
27
+ apis: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
27
28
  get: PropTypes.Validator<(...args: any[]) => any>;
28
- }>>;
29
+ }>>>;
29
30
  children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
30
31
  };
31
32
  };
@@ -33,7 +34,7 @@ declare const ApiProvider: {
33
34
  /**
34
35
  * @public
35
36
  */
36
- declare type ApiFactoryHolder = {
37
+ type ApiFactoryHolder = {
37
38
  get<T>(api: ApiRef<T>): ApiFactory<T, T, {
38
39
  [key in string]: unknown;
39
40
  }> | undefined;
@@ -63,7 +64,7 @@ declare class ApiResolver implements ApiHolder {
63
64
  * Scope type when registering API factories.
64
65
  * @public
65
66
  */
66
- declare type ApiFactoryScope = 'default' | 'app' | 'static';
67
+ type ApiFactoryScope = 'default' | 'app' | 'static';
67
68
  /**
68
69
  * ApiFactoryRegistry is an ApiFactoryHolder implementation that enables
69
70
  * registration of API Factories with different scope.
@@ -95,7 +96,7 @@ declare class ApiFactoryRegistry implements ApiFactoryHolder {
95
96
  * Create options for OAuth APIs.
96
97
  * @public
97
98
  */
98
- declare type OAuthApiCreateOptions = AuthApiCreateOptions & {
99
+ type OAuthApiCreateOptions = AuthApiCreateOptions & {
99
100
  oauthRequestApi: OAuthRequestApi;
100
101
  defaultScopes?: string[];
101
102
  };
@@ -103,7 +104,7 @@ declare type OAuthApiCreateOptions = AuthApiCreateOptions & {
103
104
  * Generic create options for auth APIs.
104
105
  * @public
105
106
  */
106
- declare type AuthApiCreateOptions = {
107
+ type AuthApiCreateOptions = {
107
108
  discoveryApi: DiscoveryApi;
108
109
  environment?: string;
109
110
  provider?: AuthProviderInfo;
@@ -141,7 +142,7 @@ declare class GoogleAuth {
141
142
  * OAuth2 create options.
142
143
  * @public
143
144
  */
144
- declare type OAuth2CreateOptions = OAuthApiCreateOptions & {
145
+ type OAuth2CreateOptions = OAuthApiCreateOptions & {
145
146
  scopeTransform?: (scopes: string[]) => string[];
146
147
  };
147
148
  /**
@@ -169,7 +170,7 @@ declare class OAuth2 implements OAuthApi, OpenIdConnectApi, ProfileInfoApi, Back
169
170
  *
170
171
  * @public
171
172
  */
172
- declare type OAuth2Session = {
173
+ type OAuth2Session = {
173
174
  providerInfo: {
174
175
  idToken: string;
175
176
  accessToken: string;
@@ -211,14 +212,33 @@ declare class SamlAuth implements ProfileInfoApi, BackstageIdentityApi, SessionA
211
212
  * @public
212
213
  */
213
214
  declare class MicrosoftAuth {
214
- static create(options: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
215
+ private oauth2;
216
+ private configApi;
217
+ private environment;
218
+ private provider;
219
+ private oauthRequestApi;
220
+ private discoveryApi;
221
+ private scopeTransform;
222
+ private static MicrosoftGraphID;
223
+ static create(options: OAuth2CreateOptions): typeof microsoftAuthApiRef.T;
224
+ private constructor();
225
+ private microsoftGraph;
226
+ private static resourceForScopes;
227
+ private static resourceForScope;
228
+ getAccessToken(scope?: string | string[], options?: AuthRequestOptions): Promise<string>;
229
+ getIdToken(options?: AuthRequestOptions): Promise<string>;
230
+ getProfile(options?: AuthRequestOptions): Promise<_backstage_core_plugin_api.ProfileInfo | undefined>;
231
+ getBackstageIdentity(options?: AuthRequestOptions): Promise<_backstage_core_plugin_api.BackstageIdentityResponse | undefined>;
232
+ signIn(): Promise<void>;
233
+ signOut(): Promise<void>;
234
+ sessionState$(): _backstage_types.Observable<_backstage_core_plugin_api.SessionState>;
215
235
  }
216
236
 
217
237
  /**
218
238
  * OneLogin auth provider create options.
219
239
  * @public
220
240
  */
221
- declare type OneLoginAuthCreateOptions = {
241
+ type OneLoginAuthCreateOptions = {
222
242
  configApi?: ConfigApi;
223
243
  discoveryApi: DiscoveryApi;
224
244
  oauthRequestApi: OAuthRequestApi;
@@ -239,7 +259,7 @@ declare class OneLoginAuth {
239
259
  *
240
260
  * @public
241
261
  */
242
- declare type BitbucketSession = {
262
+ type BitbucketSession = {
243
263
  providerInfo: {
244
264
  accessToken: string;
245
265
  scopes: Set<string>;
@@ -263,7 +283,7 @@ declare class BitbucketAuth {
263
283
  *
264
284
  * @public
265
285
  */
266
- declare type BitbucketServerSession = {
286
+ type BitbucketServerSession = {
267
287
  providerInfo: {
268
288
  accessToken: string;
269
289
  scopes: Set<string>;
@@ -604,7 +624,7 @@ declare function AppRouter(props: AppRouterProps): JSX.Element;
604
624
  *
605
625
  * @public
606
626
  */
607
- declare type BootErrorPageProps = {
627
+ type BootErrorPageProps = {
608
628
  step: 'load-config' | 'load-chunk';
609
629
  error: Error;
610
630
  };
@@ -613,7 +633,7 @@ declare type BootErrorPageProps = {
613
633
  *
614
634
  * @public
615
635
  */
616
- declare type SignInPageProps = {
636
+ type SignInPageProps = {
617
637
  /**
618
638
  * Set the IdentityApi on successful sign-in. This should only be called once.
619
639
  */
@@ -624,7 +644,7 @@ declare type SignInPageProps = {
624
644
  *
625
645
  * @public
626
646
  */
627
- declare type ErrorBoundaryFallbackProps = {
647
+ type ErrorBoundaryFallbackProps = {
628
648
  plugin?: BackstagePlugin;
629
649
  error: Error;
630
650
  resetError: () => void;
@@ -634,7 +654,7 @@ declare type ErrorBoundaryFallbackProps = {
634
654
  *
635
655
  * @public
636
656
  */
637
- declare type AppComponents = {
657
+ type AppComponents = {
638
658
  NotFoundErrorPage: ComponentType<{}>;
639
659
  BootErrorPage: ComponentType<BootErrorPageProps>;
640
660
  Progress: ComponentType<{}>;
@@ -659,7 +679,7 @@ declare type AppComponents = {
659
679
  *
660
680
  * @public
661
681
  */
662
- declare type AppIcons = {
682
+ type AppIcons = {
663
683
  'kind:api': IconComponent;
664
684
  'kind:component': IconComponent;
665
685
  'kind:domain': IconComponent;
@@ -690,13 +710,13 @@ declare type AppIcons = {
690
710
  *
691
711
  * @public
692
712
  */
693
- declare type AppConfigLoader = () => Promise<AppConfig[]>;
713
+ type AppConfigLoader = () => Promise<AppConfig[]>;
694
714
  /**
695
715
  * Extracts a union of the keys in a map whose value extends the given type
696
716
  *
697
717
  * @ignore
698
718
  */
699
- declare type KeysWithType<Obj extends {
719
+ type KeysWithType<Obj extends {
700
720
  [key in string]: any;
701
721
  }, Type> = {
702
722
  [key in keyof Obj]: Obj[key] extends Type ? key : never;
@@ -706,7 +726,7 @@ declare type KeysWithType<Obj extends {
706
726
  *
707
727
  * @ignore
708
728
  */
709
- declare type PartialKeys<Map extends {
729
+ type PartialKeys<Map extends {
710
730
  [name in string]: any;
711
731
  }, Keys extends keyof Map> = Partial<Pick<Map, Keys>> & Required<Omit<Map, Keys>>;
712
732
  /**
@@ -714,7 +734,7 @@ declare type PartialKeys<Map extends {
714
734
  *
715
735
  * @ignore
716
736
  */
717
- declare type TargetRouteMap<ExternalRoutes extends {
737
+ type TargetRouteMap<ExternalRoutes extends {
718
738
  [name: string]: ExternalRouteRef;
719
739
  }> = {
720
740
  [name in keyof ExternalRoutes]: ExternalRoutes[name] extends ExternalRouteRef<infer Params, any> ? RouteRef<Params> | SubRouteRef<Params> : never;
@@ -725,7 +745,7 @@ declare type TargetRouteMap<ExternalRoutes extends {
725
745
  *
726
746
  * @public
727
747
  */
728
- declare type AppRouteBinder = <ExternalRoutes extends {
748
+ type AppRouteBinder = <ExternalRoutes extends {
729
749
  [name: string]: ExternalRouteRef;
730
750
  }>(externalRoutes: ExternalRoutes, targetRoutes: PartialKeys<TargetRouteMap<ExternalRoutes>, KeysWithType<ExternalRoutes, ExternalRouteRef<any, true>>>) => void;
731
751
  /**
@@ -733,7 +753,7 @@ declare type AppRouteBinder = <ExternalRoutes extends {
733
753
  *
734
754
  * @public
735
755
  */
736
- declare type AppOptions = {
756
+ type AppOptions = {
737
757
  /**
738
758
  * A collection of ApiFactories to register in the application to either
739
759
  * add new ones, or override factories provided by default or by plugins.
@@ -840,7 +860,7 @@ declare type AppOptions = {
840
860
  *
841
861
  * @public
842
862
  */
843
- declare type BackstageApp = {
863
+ type BackstageApp = {
844
864
  /**
845
865
  * Returns all plugins registered for the app.
846
866
  */
@@ -894,7 +914,7 @@ declare type BackstageApp = {
894
914
  *
895
915
  * @public
896
916
  */
897
- declare type AppContext = {
917
+ type AppContext = {
898
918
  /**
899
919
  * Get a list of all plugins that are installed in the app.
900
920
  */
@@ -948,7 +968,7 @@ declare const defaultConfigLoader: AppConfigLoader;
948
968
  *
949
969
  * @public
950
970
  */
951
- declare type FlatRoutesProps = {
971
+ type FlatRoutesProps = {
952
972
  children: ReactNode;
953
973
  };
954
974
  /**
@@ -969,7 +989,7 @@ declare const FlatRoutes: (props: FlatRoutesProps) => JSX.Element | null;
969
989
  *
970
990
  * @public
971
991
  */
972
- declare type FeatureFlaggedProps = {
992
+ type FeatureFlaggedProps = {
973
993
  children: ReactNode;
974
994
  } & ({
975
995
  with: string;
package/dist/index.esm.js CHANGED
@@ -262,9 +262,12 @@ class DefaultAuthConnector {
262
262
  }
263
263
  return this.authRequester(options.scopes);
264
264
  }
265
- async refreshSession() {
265
+ async refreshSession(scopes) {
266
266
  const res = await fetch(
267
- await this.buildUrl("/refresh", { optional: true }),
267
+ await this.buildUrl("/refresh", {
268
+ optional: true,
269
+ ...scopes && { scope: this.joinScopesFunc(scopes) }
270
+ }),
268
271
  {
269
272
  headers: {
270
273
  "x-requested-with": "XMLHttpRequest"
@@ -606,7 +609,9 @@ class RefreshingAuthSessionManager {
606
609
  return this.currentSession;
607
610
  }
608
611
  try {
609
- const refreshedSession = await this.collapsedSessionRefresh();
612
+ const refreshedSession = await this.collapsedSessionRefresh(
613
+ options.scopes
614
+ );
610
615
  const currentScopes = this.sessionScopesFunc(this.currentSession);
611
616
  const refreshedScopes = this.sessionScopesFunc(refreshedSession);
612
617
  if (hasScopes$1(refreshedScopes, currentScopes)) {
@@ -622,7 +627,7 @@ class RefreshingAuthSessionManager {
622
627
  }
623
628
  if (!this.currentSession && !options.instantPopup) {
624
629
  try {
625
- const newSession = await this.collapsedSessionRefresh();
630
+ const newSession = await this.collapsedSessionRefresh(options.scopes);
626
631
  this.currentSession = newSession;
627
632
  return this.getSession(options);
628
633
  } catch {
@@ -646,11 +651,11 @@ class RefreshingAuthSessionManager {
646
651
  sessionState$() {
647
652
  return this.stateTracker.sessionState$();
648
653
  }
649
- async collapsedSessionRefresh() {
654
+ async collapsedSessionRefresh(scopes) {
650
655
  if (this.refreshPromise) {
651
656
  return this.refreshPromise;
652
657
  }
653
- this.refreshPromise = this.connector.refreshSession();
658
+ this.refreshPromise = this.connector.refreshSession(scopes);
654
659
  try {
655
660
  const session = await this.refreshPromise;
656
661
  this.stateTracker.setIsSignedIn(true);
@@ -1108,8 +1113,11 @@ const DEFAULT_PROVIDER$4 = {
1108
1113
  title: "Microsoft",
1109
1114
  icon: () => null
1110
1115
  };
1111
- class MicrosoftAuth {
1116
+ const _MicrosoftAuth = class {
1112
1117
  static create(options) {
1118
+ return new _MicrosoftAuth(options);
1119
+ }
1120
+ constructor(options) {
1113
1121
  const {
1114
1122
  configApi,
1115
1123
  environment = "development",
@@ -1122,18 +1130,101 @@ class MicrosoftAuth {
1122
1130
  "profile",
1123
1131
  "email",
1124
1132
  "User.Read"
1125
- ]
1133
+ ],
1134
+ scopeTransform = (scopes) => scopes.concat("offline_access")
1126
1135
  } = options;
1127
- return OAuth2.create({
1128
- configApi,
1129
- discoveryApi,
1130
- oauthRequestApi,
1131
- provider,
1132
- environment,
1133
- defaultScopes
1134
- });
1136
+ this.configApi = configApi;
1137
+ this.environment = environment;
1138
+ this.provider = provider;
1139
+ this.oauthRequestApi = oauthRequestApi;
1140
+ this.discoveryApi = discoveryApi;
1141
+ this.scopeTransform = scopeTransform;
1142
+ this.oauth2 = {
1143
+ [_MicrosoftAuth.MicrosoftGraphID]: OAuth2.create({
1144
+ configApi: this.configApi,
1145
+ discoveryApi: this.discoveryApi,
1146
+ oauthRequestApi: this.oauthRequestApi,
1147
+ provider: this.provider,
1148
+ environment: this.environment,
1149
+ scopeTransform: this.scopeTransform,
1150
+ defaultScopes
1151
+ })
1152
+ };
1135
1153
  }
1136
- }
1154
+ microsoftGraph() {
1155
+ return this.oauth2[_MicrosoftAuth.MicrosoftGraphID];
1156
+ }
1157
+ static resourceForScopes(scope) {
1158
+ var _a;
1159
+ const audiences = scope.split(" ").map(_MicrosoftAuth.resourceForScope).filter((aud) => aud !== "openid");
1160
+ if (audiences.length > 1) {
1161
+ return Promise.reject(
1162
+ new Error(
1163
+ `Requested access token with scopes from multiple Azure resources: ${audiences.join(
1164
+ ", "
1165
+ )}. Access tokens can only have a single audience.`
1166
+ )
1167
+ );
1168
+ }
1169
+ const audience = (_a = audiences[0]) != null ? _a : _MicrosoftAuth.MicrosoftGraphID;
1170
+ return Promise.resolve(audience);
1171
+ }
1172
+ static resourceForScope(scope) {
1173
+ var _a;
1174
+ const groups = (_a = scope.match(/^(?<resourceURI>.*)\/(?<scp>[^\/]*)$/)) == null ? void 0 : _a.groups;
1175
+ if (groups) {
1176
+ const { resourceURI } = groups;
1177
+ const aud = resourceURI.replace(/^api:\/\//, "");
1178
+ return aud;
1179
+ }
1180
+ switch (scope) {
1181
+ case "email":
1182
+ case "openid":
1183
+ case "offline_access":
1184
+ case "profile": {
1185
+ return "openid";
1186
+ }
1187
+ default:
1188
+ return _MicrosoftAuth.MicrosoftGraphID;
1189
+ }
1190
+ }
1191
+ async getAccessToken(scope, options) {
1192
+ const aud = scope === void 0 ? _MicrosoftAuth.MicrosoftGraphID : await _MicrosoftAuth.resourceForScopes(
1193
+ Array.isArray(scope) ? scope.join(" ") : scope
1194
+ );
1195
+ if (!(aud in this.oauth2)) {
1196
+ this.oauth2[aud] = OAuth2.create({
1197
+ configApi: this.configApi,
1198
+ discoveryApi: this.discoveryApi,
1199
+ oauthRequestApi: this.oauthRequestApi,
1200
+ provider: this.provider,
1201
+ environment: this.environment,
1202
+ scopeTransform: this.scopeTransform
1203
+ });
1204
+ }
1205
+ return this.oauth2[aud].getAccessToken(scope, options);
1206
+ }
1207
+ getIdToken(options) {
1208
+ return this.microsoftGraph().getIdToken(options);
1209
+ }
1210
+ getProfile(options) {
1211
+ return this.microsoftGraph().getProfile(options);
1212
+ }
1213
+ getBackstageIdentity(options) {
1214
+ return this.microsoftGraph().getBackstageIdentity(options);
1215
+ }
1216
+ signIn() {
1217
+ return this.microsoftGraph().signIn();
1218
+ }
1219
+ signOut() {
1220
+ return this.microsoftGraph().signOut();
1221
+ }
1222
+ sessionState$() {
1223
+ return this.microsoftGraph().sessionState$();
1224
+ }
1225
+ };
1226
+ let MicrosoftAuth = _MicrosoftAuth;
1227
+ MicrosoftAuth.MicrosoftGraphID = "00000003-0000-0000-c000-000000000000";
1137
1228
 
1138
1229
  const DEFAULT_PROVIDER$3 = {
1139
1230
  id: "onelogin",