@backstage/plugin-auth-backend 0.0.0-nightly-2022122206 → 0.0.0-nightly-20220210021913

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,6 +1,40 @@
1
1
  # @backstage/plugin-auth-backend
2
2
 
3
- ## 0.0.0-nightly-2022122206
3
+ ## 0.0.0-nightly-20220210021913
4
+
5
+ ### Minor Changes
6
+
7
+ - 08fcda13ef: The `callbackUrl` option of `OAuthAdapter` is now required.
8
+
9
+ ### Patch Changes
10
+
11
+ - 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2
12
+
13
+ This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7
14
+
15
+ - 3396bc5973: Enabled refresh for the Atlassian provider.
16
+ - 08fcda13ef: Added a new `cookieConfigurer` option to `AuthProviderConfig` that makes it possible to override the default logic for configuring OAuth provider cookies.
17
+ - Updated dependencies
18
+ - @backstage/backend-common@0.0.0-nightly-20220210021913
19
+
20
+ ## 0.10.0-next.0
21
+
22
+ ### Minor Changes
23
+
24
+ - 08fcda13ef: The `callbackUrl` option of `OAuthAdapter` is now required.
25
+
26
+ ### Patch Changes
27
+
28
+ - 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2
29
+
30
+ This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7
31
+
32
+ - 3396bc5973: Enabled refresh for the Atlassian provider.
33
+ - 08fcda13ef: Added a new `cookieConfigurer` option to `AuthProviderConfig` that makes it possible to override the default logic for configuring OAuth provider cookies.
34
+ - Updated dependencies
35
+ - @backstage/backend-common@0.10.7-next.0
36
+
37
+ ## 0.9.0
4
38
 
5
39
  ### Minor Changes
6
40
 
@@ -30,7 +64,21 @@
30
64
 
31
65
  ### Patch Changes
32
66
 
67
+ - 9d75a939b6: Fixed a bug where providers that tracked the granted scopes through a cookie would not take failed authentication attempts into account.
33
68
  - 28a5f9d0b1: chore(deps): bump `passport` from 0.4.1 to 0.5.2
69
+ - 5d09bdd1de: Added custom `callbackUrl` support for multiple providers. `v0.8.0` introduced this change for `github`, and now we're adding the same capability to the following providers: `atlassian, auth0, bitbucket, gitlab, google, microsoft, oauth2, oidc, okta, onelogin`.
70
+ - 648606b3ac: Added support for storing static GitHub access tokens in cookies and using them to refresh the Backstage session.
71
+ - Updated dependencies
72
+ - @backstage/backend-common@0.10.6
73
+
74
+ ## 0.9.0-next.1
75
+
76
+ ### Patch Changes
77
+
78
+ - 9d75a939b6: Fixed a bug where providers that tracked the granted scopes through a cookie would not take failed authentication attempts into account.
79
+ - 648606b3ac: Added support for storing static GitHub access tokens in cookies and using them to refresh the Backstage session.
80
+ - Updated dependencies
81
+ - @backstage/backend-common@0.10.6-next.0
34
82
 
35
83
  ## 0.9.0-next.0
36
84
 
package/dist/index.cjs.js CHANGED
@@ -149,15 +149,14 @@ const verifyNonce = (req, providerId) => {
149
149
  throw new Error("Invalid nonce");
150
150
  }
151
151
  };
152
- const getCookieConfig = (authUrl, providerId) => {
153
- const { hostname: cookieDomain, pathname, protocol } = authUrl;
152
+ const defaultCookieConfigurer = ({
153
+ callbackUrl,
154
+ providerId
155
+ }) => {
156
+ const { hostname: domain, pathname, protocol } = new URL(callbackUrl);
154
157
  const secure = protocol === "https:";
155
- const cookiePath = pathname.endsWith(`${providerId}/handler/frame`) ? pathname.slice(0, -"/handler/frame".length) : `${pathname}/${providerId}`;
156
- return {
157
- cookieDomain,
158
- cookiePath,
159
- secure
160
- };
158
+ const path = pathname.endsWith(`${providerId}/handler/frame`) ? pathname.slice(0, -"/handler/frame".length) : `${pathname}/${providerId}`;
159
+ return { domain, path, secure };
161
160
  };
162
161
 
163
162
  class OAuthEnvironmentHandler {
@@ -281,58 +280,54 @@ class OAuthAdapter {
281
280
  this.setNonceCookie = (res, nonce) => {
282
281
  res.cookie(`${this.options.providerId}-nonce`, nonce, {
283
282
  maxAge: TEN_MINUTES_MS,
284
- secure: this.options.secure,
285
- sameSite: "lax",
286
- domain: this.options.cookieDomain,
287
- path: `${this.options.cookiePath}/handler`,
288
- httpOnly: true
283
+ ...this.baseCookieOptions,
284
+ path: `${this.options.cookiePath}/handler`
289
285
  });
290
286
  };
291
- this.setScopesCookie = (res, scope) => {
292
- res.cookie(`${this.options.providerId}-scope`, scope, {
293
- maxAge: TEN_MINUTES_MS,
294
- secure: this.options.secure,
295
- sameSite: "lax",
296
- domain: this.options.cookieDomain,
297
- path: `${this.options.cookiePath}/handler`,
298
- httpOnly: true
287
+ this.setGrantedScopeCookie = (res, scope) => {
288
+ res.cookie(`${this.options.providerId}-granted-scope`, scope, {
289
+ maxAge: THOUSAND_DAYS_MS,
290
+ ...this.baseCookieOptions
299
291
  });
300
292
  };
301
- this.getScopesFromCookie = (req, providerId) => {
302
- return req.cookies[`${providerId}-scope`];
293
+ this.getGrantedScopeFromCookie = (req) => {
294
+ return req.cookies[`${this.options.providerId}-granted-scope`];
303
295
  };
304
296
  this.setRefreshTokenCookie = (res, refreshToken) => {
305
297
  res.cookie(`${this.options.providerId}-refresh-token`, refreshToken, {
306
298
  maxAge: THOUSAND_DAYS_MS,
307
- secure: this.options.secure,
308
- sameSite: "lax",
309
- domain: this.options.cookieDomain,
310
- path: this.options.cookiePath,
311
- httpOnly: true
299
+ ...this.baseCookieOptions
312
300
  });
313
301
  };
314
302
  this.removeRefreshTokenCookie = (res) => {
315
303
  res.cookie(`${this.options.providerId}-refresh-token`, "", {
316
304
  maxAge: 0,
317
- secure: this.options.secure,
318
- sameSite: "lax",
319
- domain: this.options.cookieDomain,
320
- path: this.options.cookiePath,
321
- httpOnly: true
305
+ ...this.baseCookieOptions
322
306
  });
323
307
  };
308
+ this.baseCookieOptions = {
309
+ httpOnly: true,
310
+ sameSite: "lax",
311
+ secure: this.options.secure,
312
+ path: this.options.cookiePath,
313
+ domain: this.options.cookieDomain
314
+ };
324
315
  }
325
316
  static fromConfig(config, handlers, options) {
326
317
  var _a;
327
318
  const { origin: appOrigin } = new url.URL(config.appUrl);
328
- const authUrl = new url.URL((_a = options.callbackUrl) != null ? _a : config.baseUrl);
329
- const { cookieDomain, cookiePath, secure } = getCookieConfig(authUrl, options.providerId);
319
+ const cookieConfigurer = (_a = config.cookieConfigurer) != null ? _a : defaultCookieConfigurer;
320
+ const cookieConfig = cookieConfigurer({
321
+ providerId: options.providerId,
322
+ baseUrl: config.baseUrl,
323
+ callbackUrl: options.callbackUrl
324
+ });
330
325
  return new OAuthAdapter(handlers, {
331
326
  ...options,
332
327
  appOrigin,
333
- cookieDomain,
334
- cookiePath,
335
- secure,
328
+ cookieDomain: cookieConfig.domain,
329
+ cookiePath: cookieConfig.path,
330
+ secure: cookieConfig.secure,
336
331
  isOriginAllowed: config.isOriginAllowed
337
332
  });
338
333
  }
@@ -344,12 +339,12 @@ class OAuthAdapter {
344
339
  if (!env) {
345
340
  throw new errors.InputError("No env provided in request query parameters");
346
341
  }
347
- if (this.options.persistScopes) {
348
- this.setScopesCookie(res, scope);
349
- }
350
342
  const nonce = crypto__default["default"].randomBytes(16).toString("base64");
351
343
  this.setNonceCookie(res, nonce);
352
344
  const state = { nonce, env, origin };
345
+ if (this.options.persistScopes) {
346
+ state.scope = scope;
347
+ }
353
348
  const forwardReq = Object.assign(req, { scope, state });
354
349
  const { url, status } = await this.handlers.start(forwardReq);
355
350
  res.statusCode = status || 302;
@@ -374,9 +369,9 @@ class OAuthAdapter {
374
369
  }
375
370
  verifyNonce(req, this.options.providerId);
376
371
  const { response, refreshToken } = await this.handlers.handler(req);
377
- if (this.options.persistScopes) {
378
- const grantedScopes = this.getScopesFromCookie(req, this.options.providerId);
379
- response.providerInfo.scope = grantedScopes;
372
+ if (this.options.persistScopes && state.scope) {
373
+ this.setGrantedScopeCookie(res, state.scope);
374
+ response.providerInfo.scope = state.scope;
380
375
  }
381
376
  if (refreshToken && !this.options.disableRefresh) {
382
377
  this.setRefreshTokenCookie(res, refreshToken);
@@ -414,7 +409,10 @@ class OAuthAdapter {
414
409
  if (!refreshToken) {
415
410
  throw new errors.InputError("Missing session cookie");
416
411
  }
417
- const scope = (_b = (_a = req.query.scope) == null ? void 0 : _a.toString()) != null ? _b : "";
412
+ let scope = (_b = (_a = req.query.scope) == null ? void 0 : _a.toString()) != null ? _b : "";
413
+ if (this.options.persistScopes) {
414
+ scope = this.getGrantedScopeFromCookie(req);
415
+ }
418
416
  const forwardReq = Object.assign(req, { scope, refreshToken });
419
417
  const { response, refreshToken: newRefreshToken } = await this.handlers.refresh(forwardReq);
420
418
  const backstageIdentity = await this.populateIdentity(response.backstageIdentity);
@@ -718,7 +716,8 @@ const createAtlassianProvider = (options) => {
718
716
  const clientId = envConfig.getString("clientId");
719
717
  const clientSecret = envConfig.getString("clientSecret");
720
718
  const scopes = envConfig.getString("scopes");
721
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
719
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
720
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
722
721
  const catalogIdentityClient = new CatalogIdentityClient({
723
722
  catalogApi,
724
723
  tokenManager
@@ -736,9 +735,9 @@ const createAtlassianProvider = (options) => {
736
735
  tokenIssuer
737
736
  });
738
737
  return OAuthAdapter.fromConfig(globalConfig, provider, {
739
- disableRefresh: true,
740
738
  providerId,
741
- tokenIssuer
739
+ tokenIssuer,
740
+ callbackUrl
742
741
  });
743
742
  });
744
743
  };
@@ -854,7 +853,8 @@ const createAuth0Provider = (options) => {
854
853
  const clientId = envConfig.getString("clientId");
855
854
  const clientSecret = envConfig.getString("clientSecret");
856
855
  const domain = envConfig.getString("domain");
857
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
856
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
857
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
858
858
  const catalogIdentityClient = new CatalogIdentityClient({
859
859
  catalogApi,
860
860
  tokenManager
@@ -877,7 +877,8 @@ const createAuth0Provider = (options) => {
877
877
  return OAuthAdapter.fromConfig(globalConfig, provider, {
878
878
  disableRefresh: true,
879
879
  providerId,
880
- tokenIssuer
880
+ tokenIssuer,
881
+ callbackUrl
881
882
  });
882
883
  });
883
884
  };
@@ -1128,7 +1129,8 @@ const createBitbucketProvider = (options) => {
1128
1129
  var _a;
1129
1130
  const clientId = envConfig.getString("clientId");
1130
1131
  const clientSecret = envConfig.getString("clientSecret");
1131
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1132
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
1133
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1132
1134
  const catalogIdentityClient = new CatalogIdentityClient({
1133
1135
  catalogApi,
1134
1136
  tokenManager
@@ -1149,11 +1151,14 @@ const createBitbucketProvider = (options) => {
1149
1151
  return OAuthAdapter.fromConfig(globalConfig, provider, {
1150
1152
  disableRefresh: false,
1151
1153
  providerId,
1152
- tokenIssuer
1154
+ tokenIssuer,
1155
+ callbackUrl
1153
1156
  });
1154
1157
  });
1155
1158
  };
1156
1159
 
1160
+ const ACCESS_TOKEN_PREFIX = "access-token.";
1161
+ const BACKSTAGE_SESSION_EXPIRATION = 3600;
1157
1162
  class GithubAuthProvider {
1158
1163
  constructor(options) {
1159
1164
  this.signInResolver = options.signInResolver;
@@ -1181,21 +1186,43 @@ class GithubAuthProvider {
1181
1186
  }
1182
1187
  async handler(req) {
1183
1188
  const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
1189
+ let refreshToken = privateInfo.refreshToken;
1190
+ if (!refreshToken && !result.params.expires_in) {
1191
+ refreshToken = ACCESS_TOKEN_PREFIX + result.accessToken;
1192
+ }
1184
1193
  return {
1185
1194
  response: await this.handleResult(result),
1186
- refreshToken: privateInfo.refreshToken
1195
+ refreshToken
1187
1196
  };
1188
1197
  }
1189
1198
  async refresh(req) {
1190
- const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
1191
- const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
1199
+ const { scope, refreshToken } = req;
1200
+ if (refreshToken == null ? void 0 : refreshToken.startsWith(ACCESS_TOKEN_PREFIX)) {
1201
+ const accessToken = refreshToken.slice(ACCESS_TOKEN_PREFIX.length);
1202
+ const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken).catch((error) => {
1203
+ var _a;
1204
+ if (((_a = error.oauthError) == null ? void 0 : _a.statusCode) === 401) {
1205
+ throw new Error("Invalid access token");
1206
+ }
1207
+ throw error;
1208
+ });
1209
+ return {
1210
+ response: await this.handleResult({
1211
+ fullProfile,
1212
+ params: { scope },
1213
+ accessToken
1214
+ }),
1215
+ refreshToken
1216
+ };
1217
+ }
1218
+ const result = await executeRefreshTokenStrategy(this._strategy, refreshToken, scope);
1192
1219
  return {
1193
1220
  response: await this.handleResult({
1194
- fullProfile,
1195
- params,
1196
- accessToken
1221
+ fullProfile: await executeFetchUserProfileStrategy(this._strategy, result.accessToken),
1222
+ params: { ...result.params, scope },
1223
+ accessToken: result.accessToken
1197
1224
  }),
1198
- refreshToken
1225
+ refreshToken: result.refreshToken
1199
1226
  };
1200
1227
  }
1201
1228
  async handleResult(result) {
@@ -1206,21 +1233,28 @@ class GithubAuthProvider {
1206
1233
  };
1207
1234
  const { profile } = await this.authHandler(result, context);
1208
1235
  const expiresInStr = result.params.expires_in;
1209
- const response = {
1236
+ let expiresInSeconds = expiresInStr === void 0 ? void 0 : Number(expiresInStr);
1237
+ let backstageIdentity = void 0;
1238
+ if (this.signInResolver) {
1239
+ backstageIdentity = await this.signInResolver({
1240
+ result,
1241
+ profile
1242
+ }, context);
1243
+ if (expiresInSeconds) {
1244
+ expiresInSeconds = Math.min(expiresInSeconds, BACKSTAGE_SESSION_EXPIRATION);
1245
+ } else {
1246
+ expiresInSeconds = BACKSTAGE_SESSION_EXPIRATION;
1247
+ }
1248
+ }
1249
+ return {
1250
+ backstageIdentity,
1210
1251
  providerInfo: {
1211
1252
  accessToken: result.accessToken,
1212
1253
  scope: result.params.scope,
1213
- expiresInSeconds: expiresInStr === void 0 ? void 0 : Number(expiresInStr)
1254
+ expiresInSeconds
1214
1255
  },
1215
1256
  profile
1216
1257
  };
1217
- if (this.signInResolver) {
1218
- response.backstageIdentity = await this.signInResolver({
1219
- result,
1220
- profile
1221
- }, context);
1222
- }
1223
- return response;
1224
1258
  }
1225
1259
  }
1226
1260
  const githubDefaultSignInResolver = async (info, ctx) => {
@@ -1392,7 +1426,8 @@ const createGitlabProvider = (options) => {
1392
1426
  const clientSecret = envConfig.getString("clientSecret");
1393
1427
  const audience = envConfig.getOptionalString("audience");
1394
1428
  const baseUrl = audience || "https://gitlab.com";
1395
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1429
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
1430
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1396
1431
  const catalogIdentityClient = new CatalogIdentityClient({
1397
1432
  catalogApi,
1398
1433
  tokenManager
@@ -1418,7 +1453,8 @@ const createGitlabProvider = (options) => {
1418
1453
  return OAuthAdapter.fromConfig(globalConfig, provider, {
1419
1454
  disableRefresh: false,
1420
1455
  providerId,
1421
- tokenIssuer
1456
+ tokenIssuer,
1457
+ callbackUrl
1422
1458
  });
1423
1459
  });
1424
1460
  };
@@ -1547,7 +1583,8 @@ const createGoogleProvider = (options) => {
1547
1583
  var _a, _b;
1548
1584
  const clientId = envConfig.getString("clientId");
1549
1585
  const clientSecret = envConfig.getString("clientSecret");
1550
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1586
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
1587
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1551
1588
  const catalogIdentityClient = new CatalogIdentityClient({
1552
1589
  catalogApi,
1553
1590
  tokenManager
@@ -1574,7 +1611,8 @@ const createGoogleProvider = (options) => {
1574
1611
  return OAuthAdapter.fromConfig(globalConfig, provider, {
1575
1612
  disableRefresh: false,
1576
1613
  providerId,
1577
- tokenIssuer
1614
+ tokenIssuer,
1615
+ callbackUrl
1578
1616
  });
1579
1617
  });
1580
1618
  };
@@ -1706,7 +1744,8 @@ const createMicrosoftProvider = (options) => {
1706
1744
  const clientId = envConfig.getString("clientId");
1707
1745
  const clientSecret = envConfig.getString("clientSecret");
1708
1746
  const tenantId = envConfig.getString("tenantId");
1709
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1747
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
1748
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1710
1749
  const authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;
1711
1750
  const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
1712
1751
  const catalogIdentityClient = new CatalogIdentityClient({
@@ -1737,7 +1776,8 @@ const createMicrosoftProvider = (options) => {
1737
1776
  return OAuthAdapter.fromConfig(globalConfig, provider, {
1738
1777
  disableRefresh: false,
1739
1778
  providerId,
1740
- tokenIssuer
1779
+ tokenIssuer,
1780
+ callbackUrl
1741
1781
  });
1742
1782
  });
1743
1783
  };
@@ -1851,7 +1891,8 @@ const createOAuth2Provider = (options) => {
1851
1891
  var _a, _b, _c;
1852
1892
  const clientId = envConfig.getString("clientId");
1853
1893
  const clientSecret = envConfig.getString("clientSecret");
1854
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1894
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
1895
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1855
1896
  const authorizationUrl = envConfig.getString("authorizationUrl");
1856
1897
  const tokenUrl = envConfig.getString("tokenUrl");
1857
1898
  const scope = envConfig.getOptionalString("scope");
@@ -1887,7 +1928,8 @@ const createOAuth2Provider = (options) => {
1887
1928
  return OAuthAdapter.fromConfig(globalConfig, provider, {
1888
1929
  disableRefresh,
1889
1930
  providerId,
1890
- tokenIssuer
1931
+ tokenIssuer,
1932
+ callbackUrl
1891
1933
  });
1892
1934
  });
1893
1935
  };
@@ -2426,7 +2468,8 @@ const createOidcProvider = (options) => {
2426
2468
  var _a, _b;
2427
2469
  const clientId = envConfig.getString("clientId");
2428
2470
  const clientSecret = envConfig.getString("clientSecret");
2429
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
2471
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
2472
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
2430
2473
  const metadataUrl = envConfig.getString("metadataUrl");
2431
2474
  const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
2432
2475
  const scope = envConfig.getOptionalString("scope");
@@ -2465,7 +2508,8 @@ const createOidcProvider = (options) => {
2465
2508
  return OAuthAdapter.fromConfig(globalConfig, provider, {
2466
2509
  disableRefresh: false,
2467
2510
  providerId,
2468
- tokenIssuer
2511
+ tokenIssuer,
2512
+ callbackUrl
2469
2513
  });
2470
2514
  });
2471
2515
  };
@@ -2595,7 +2639,8 @@ const createOktaProvider = (_options) => {
2595
2639
  const clientId = envConfig.getString("clientId");
2596
2640
  const clientSecret = envConfig.getString("clientSecret");
2597
2641
  const audience = envConfig.getString("audience");
2598
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
2642
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
2643
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
2599
2644
  if (!audience.startsWith("https://")) {
2600
2645
  throw new Error("URL for 'audience' must start with 'https://'.");
2601
2646
  }
@@ -2626,7 +2671,8 @@ const createOktaProvider = (_options) => {
2626
2671
  return OAuthAdapter.fromConfig(globalConfig, provider, {
2627
2672
  disableRefresh: false,
2628
2673
  providerId,
2629
- tokenIssuer
2674
+ tokenIssuer,
2675
+ callbackUrl
2630
2676
  });
2631
2677
  });
2632
2678
  };
@@ -2729,7 +2775,8 @@ const createOneLoginProvider = (options) => {
2729
2775
  const clientId = envConfig.getString("clientId");
2730
2776
  const clientSecret = envConfig.getString("clientSecret");
2731
2777
  const issuer = envConfig.getString("issuer");
2732
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
2778
+ const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
2779
+ const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
2733
2780
  const catalogIdentityClient = new CatalogIdentityClient({
2734
2781
  catalogApi,
2735
2782
  tokenManager
@@ -2752,7 +2799,8 @@ const createOneLoginProvider = (options) => {
2752
2799
  return OAuthAdapter.fromConfig(globalConfig, provider, {
2753
2800
  disableRefresh: false,
2754
2801
  providerId,
2755
- tokenIssuer
2802
+ tokenIssuer,
2803
+ callbackUrl
2756
2804
  });
2757
2805
  });
2758
2806
  };
@@ -3025,7 +3073,11 @@ async function createRouter(options) {
3025
3073
  try {
3026
3074
  const provider = providerFactory({
3027
3075
  providerId,
3028
- globalConfig: { baseUrl: authUrl, appUrl, isOriginAllowed },
3076
+ globalConfig: {
3077
+ baseUrl: authUrl,
3078
+ appUrl,
3079
+ isOriginAllowed
3080
+ },
3029
3081
  config: providersConfig.getConfig(providerId),
3030
3082
  logger,
3031
3083
  tokenManager,