@backstage/core-app-api 1.7.0-next.2 → 1.7.0

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,44 @@
1
1
  # @backstage/core-app-api
2
2
 
3
+ ## 1.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window.
8
+ - c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when
9
+ refreshing a session. The `DefaultAuthConnector` implementation passes the
10
+ `scope` query parameter to the auth-backend plugin appropriately. The
11
+ `RefreshingAuthSessionManager` passes any scopes in its `GetSessionRequest`
12
+ appropriately.
13
+
14
+ ### Patch Changes
15
+
16
+ - 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies.
17
+ - e0c6e8b9c3c: Update peer dependencies
18
+ - Updated dependencies
19
+ - @backstage/core-plugin-api@1.5.1
20
+ - @backstage/version-bridge@1.0.4
21
+ - @backstage/config@1.0.7
22
+ - @backstage/types@1.0.2
23
+
24
+ ## 1.7.0-next.3
25
+
26
+ ### Minor Changes
27
+
28
+ - c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when
29
+ refreshing a session. The `DefaultAuthConnector` implementation passes the
30
+ `scope` query parameter to the auth-backend plugin appropriately. The
31
+ `RefreshingAuthSessionManager` passes any scopes in its `GetSessionRequest`
32
+ appropriately.
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies
37
+ - @backstage/config@1.0.7
38
+ - @backstage/core-plugin-api@1.5.1-next.1
39
+ - @backstage/types@1.0.2
40
+ - @backstage/version-bridge@1.0.4-next.0
41
+
3
42
  ## 1.7.0-next.2
4
43
 
5
44
  ### 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';
@@ -211,7 +212,26 @@ 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
  /**
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",