@backstage/plugin-auth-backend 0.4.9 → 0.5.2

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/dist/index.cjs.js CHANGED
@@ -17,12 +17,12 @@ var passportGoogleOauth20 = require('passport-google-oauth20');
17
17
  var passportMicrosoft = require('passport-microsoft');
18
18
  var got = require('got');
19
19
  var OAuth2Strategy = require('passport-oauth2');
20
+ var openidClient = require('openid-client');
20
21
  var passportOktaOauth = require('passport-okta-oauth');
21
22
  var passportBitbucketOauth2 = require('passport-bitbucket-oauth2');
22
- var fetch = require('cross-fetch');
23
+ var fetch = require('node-fetch');
23
24
  var NodeCache = require('node-cache');
24
25
  var jose = require('jose');
25
- var openidClient = require('openid-client');
26
26
  var passportSaml = require('passport-saml');
27
27
  var passportOneloginOauth = require('passport-onelogin-oauth');
28
28
  var catalogClient = require('@backstage/catalog-client');
@@ -46,14 +46,12 @@ function _interopNamespace(e) {
46
46
  var d = Object.getOwnPropertyDescriptor(e, k);
47
47
  Object.defineProperty(n, k, d.get ? d : {
48
48
  enumerable: true,
49
- get: function () {
50
- return e[k];
51
- }
49
+ get: function () { return e[k]; }
52
50
  });
53
51
  }
54
52
  });
55
53
  }
56
- n['default'] = e;
54
+ n["default"] = e;
57
55
  return Object.freeze(n);
58
56
  }
59
57
 
@@ -88,7 +86,7 @@ const makeProfileInfo = (profile, idToken) => {
88
86
  let displayName = (_b = (_a = profile.displayName) != null ? _a : profile.username) != null ? _b : profile.id;
89
87
  if ((!email || !picture || !displayName) && idToken) {
90
88
  try {
91
- const decoded = jwtDecoder__default['default'](idToken);
89
+ const decoded = jwtDecoder__default["default"](idToken);
92
90
  if (!email && decoded.email) {
93
91
  email = decoded.email;
94
92
  }
@@ -112,16 +110,16 @@ const executeRedirectStrategy = async (req, providerStrategy, options) => {
112
110
  return new Promise((resolve) => {
113
111
  const strategy = Object.create(providerStrategy);
114
112
  strategy.redirect = (url, status) => {
115
- resolve({url, status: status != null ? status : void 0});
113
+ resolve({ url, status: status != null ? status : void 0 });
116
114
  };
117
- strategy.authenticate(req, {...options});
115
+ strategy.authenticate(req, { ...options });
118
116
  });
119
117
  };
120
118
  const executeFrameHandlerStrategy = async (req, providerStrategy) => {
121
119
  return new Promise((resolve, reject) => {
122
120
  const strategy = Object.create(providerStrategy);
123
121
  strategy.success = (result, privateInfo) => {
124
- resolve({result, privateInfo});
122
+ resolve({ result, privateInfo });
125
123
  };
126
124
  strategy.fail = (info) => {
127
125
  var _a;
@@ -193,7 +191,7 @@ const readState = (stateString) => {
193
191
  return state;
194
192
  };
195
193
  const encodeState = (state) => {
196
- const stateString = new URLSearchParams(pickBy__default['default'](state, (value) => value !== void 0)).toString();
194
+ const stateString = new URLSearchParams(pickBy__default["default"](state, (value) => value !== void 0)).toString();
197
195
  return Buffer.from(stateString, "utf-8").toString("hex");
198
196
  };
199
197
  const verifyNonce = (req, providerId) => {
@@ -218,7 +216,7 @@ class OAuthEnvironmentHandler {
218
216
  }
219
217
  static mapConfig(config, factoryFunc) {
220
218
  const envs = config.keys();
221
- const handlers = new Map();
219
+ const handlers = /* @__PURE__ */ new Map();
222
220
  for (const env of envs) {
223
221
  const envConfig = config.getConfig(env);
224
222
  const handler = factoryFunc(envConfig);
@@ -287,11 +285,11 @@ const postMessageResponse = (res, appOrigin, response) => {
287
285
  window.close();
288
286
  }, 100); // same as the interval of the core-app-api lib/loginPopup.ts (to address race conditions)
289
287
  `;
290
- const hash = crypto__default['default'].createHash("sha256").update(script).digest("base64");
288
+ const hash = crypto__default["default"].createHash("sha256").update(script).digest("base64");
291
289
  res.setHeader("Content-Type", "text/html");
292
290
  res.setHeader("X-Frame-Options", "sameorigin");
293
291
  res.setHeader("Content-Security-Policy", `script-src 'sha256-${hash}'`);
294
- res.end(`<html><body><script>${script}</script></body></html>`);
292
+ res.end(`<html><body><script>${script}<\/script></body></html>`);
295
293
  };
296
294
  const ensuresXRequestedWith = (req) => {
297
295
  const requiredHeader = req.header("X-Requested-With");
@@ -301,6 +299,25 @@ const ensuresXRequestedWith = (req) => {
301
299
  return true;
302
300
  };
303
301
 
302
+ function parseJwtPayload(token) {
303
+ const [_header, payload, _signature] = token.split(".");
304
+ return JSON.parse(Buffer.from(payload, "base64").toString());
305
+ }
306
+ function prepareBackstageIdentityResponse(result) {
307
+ const { sub, ent } = parseJwtPayload(result.token);
308
+ return {
309
+ ...{
310
+ idToken: result.token,
311
+ ...result
312
+ },
313
+ identity: {
314
+ type: "user",
315
+ userEntityRef: sub,
316
+ ownershipEntityRefs: ent != null ? ent : []
317
+ }
318
+ };
319
+ }
320
+
304
321
  const THOUSAND_DAYS_MS = 1e3 * 24 * 60 * 60 * 1e3;
305
322
  const TEN_MINUTES_MS = 600 * 1e3;
306
323
  class OAuthAdapter {
@@ -352,7 +369,7 @@ class OAuthAdapter {
352
369
  };
353
370
  }
354
371
  static fromConfig(config, handlers, options) {
355
- const {origin: appOrigin} = new url.URL(config.appUrl);
372
+ const { origin: appOrigin } = new url.URL(config.appUrl);
356
373
  const secure = config.baseUrl.startsWith("https://");
357
374
  const url$1 = new url.URL(config.baseUrl);
358
375
  const cookiePath = `${url$1.pathname}/${options.providerId}`;
@@ -376,11 +393,11 @@ class OAuthAdapter {
376
393
  if (this.options.persistScopes) {
377
394
  this.setScopesCookie(res, scope);
378
395
  }
379
- const nonce = crypto__default['default'].randomBytes(16).toString("base64");
396
+ const nonce = crypto__default["default"].randomBytes(16).toString("base64");
380
397
  this.setNonceCookie(res, nonce);
381
- const state = {nonce, env, origin};
382
- const forwardReq = Object.assign(req, {scope, state});
383
- const {url, status} = await this.handlers.start(forwardReq);
398
+ const state = { nonce, env, origin };
399
+ const forwardReq = Object.assign(req, { scope, state });
400
+ const { url, status } = await this.handlers.start(forwardReq);
384
401
  res.statusCode = status || 302;
385
402
  res.setHeader("Location", url);
386
403
  res.setHeader("Content-Length", "0");
@@ -402,7 +419,7 @@ class OAuthAdapter {
402
419
  }
403
420
  }
404
421
  verifyNonce(req, this.options.providerId);
405
- const {response, refreshToken} = await this.handlers.handler(req);
422
+ const { response, refreshToken } = await this.handlers.handler(req);
406
423
  if (this.options.persistScopes) {
407
424
  const grantedScopes = this.getScopesFromCookie(req, this.options.providerId);
408
425
  response.providerInfo.scope = grantedScopes;
@@ -410,16 +427,16 @@ class OAuthAdapter {
410
427
  if (refreshToken && !this.options.disableRefresh) {
411
428
  this.setRefreshTokenCookie(res, refreshToken);
412
429
  }
413
- await this.populateIdentity(response.backstageIdentity);
430
+ const identity = await this.populateIdentity(response.backstageIdentity);
414
431
  return postMessageResponse(res, appOrigin, {
415
432
  type: "authorization_response",
416
- response
433
+ response: { ...response, backstageIdentity: identity }
417
434
  });
418
435
  } catch (error) {
419
- const {name, message} = errors.isError(error) ? error : new Error("Encountered invalid error");
436
+ const { name, message } = errors.isError(error) ? error : new Error("Encountered invalid error");
420
437
  return postMessageResponse(res, appOrigin, {
421
438
  type: "authorization_response",
422
- error: {name, message}
439
+ error: { name, message }
423
440
  });
424
441
  }
425
442
  }
@@ -444,28 +461,32 @@ class OAuthAdapter {
444
461
  throw new errors.InputError("Missing session cookie");
445
462
  }
446
463
  const scope = (_b = (_a = req.query.scope) == null ? void 0 : _a.toString()) != null ? _b : "";
447
- const forwardReq = Object.assign(req, {scope, refreshToken});
464
+ const forwardReq = Object.assign(req, { scope, refreshToken });
448
465
  const response = await this.handlers.refresh(forwardReq);
449
- await this.populateIdentity(response.backstageIdentity);
466
+ const backstageIdentity = await this.populateIdentity(response.backstageIdentity);
450
467
  if (response.providerInfo.refreshToken && response.providerInfo.refreshToken !== refreshToken) {
451
468
  this.setRefreshTokenCookie(res, response.providerInfo.refreshToken);
452
469
  }
453
- res.status(200).json(response);
470
+ res.status(200).json({ ...response, backstageIdentity });
454
471
  } catch (error) {
455
472
  throw new errors.AuthenticationError("Refresh failed", error);
456
473
  }
457
474
  }
458
475
  async populateIdentity(identity) {
459
476
  if (!identity) {
460
- return;
477
+ return void 0;
461
478
  }
462
- if (!(identity.token || identity.idToken)) {
463
- identity.token = await this.options.tokenIssuer.issueToken({
464
- claims: {sub: identity.id}
465
- });
466
- } else if (!identity.token && identity.idToken) {
467
- identity.token = identity.idToken;
479
+ if (identity.token) {
480
+ return prepareBackstageIdentityResponse(identity);
468
481
  }
482
+ const userEntityRef = catalogModel.stringifyEntityRef(catalogModel.parseEntityRef(identity.id, {
483
+ defaultKind: "user",
484
+ defaultNamespace: catalogModel.ENTITY_DEFAULT_NAMESPACE
485
+ }));
486
+ const token = await this.options.tokenIssuer.issueToken({
487
+ claims: { sub: userEntityRef }
488
+ });
489
+ return prepareBackstageIdentityResponse({ ...identity, token });
469
490
  }
470
491
  }
471
492
 
@@ -482,9 +503,9 @@ class CatalogIdentityClient {
482
503
  filter[`metadata.annotations.${key}`] = value;
483
504
  }
484
505
  const token = await this.tokenIssuer.issueToken({
485
- claims: {sub: "backstage.io/auth-backend"}
506
+ claims: { sub: "backstage.io/auth-backend" }
486
507
  });
487
- const {items} = await this.catalogApi.getEntities({filter}, {token});
508
+ const { items } = await this.catalogApi.getEntities({ filter }, { token });
488
509
  if (items.length !== 1) {
489
510
  if (items.length > 1) {
490
511
  throw new errors.ConflictError("User lookup resulted in multiple matches");
@@ -494,10 +515,8 @@ class CatalogIdentityClient {
494
515
  }
495
516
  return items[0];
496
517
  }
497
- async resolveCatalogMembership({
498
- entityRefs,
499
- logger
500
- }) {
518
+ async resolveCatalogMembership(query) {
519
+ const { entityRefs, logger } = query;
501
520
  const resolvedEntityRefs = entityRefs.map((ref) => {
502
521
  try {
503
522
  const parsedRef = catalogModel.parseEntityRef(ref.toLocaleLowerCase("en-US"), {
@@ -515,7 +534,7 @@ class CatalogIdentityClient {
515
534
  "metadata.namespace": ref.namespace,
516
535
  "metadata.name": ref.name
517
536
  }));
518
- const entities = await this.catalogApi.getEntities({filter}).then((r) => r.items);
537
+ const entities = await this.catalogApi.getEntities({ filter }).then((r) => r.items);
519
538
  if (entityRefs.length !== entities.length) {
520
539
  const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
521
540
  const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
@@ -559,7 +578,7 @@ class GithubAuthProvider {
559
578
  userProfileURL: options.userProfileUrl,
560
579
  authorizationURL: options.authorizationUrl
561
580
  }, (accessToken, refreshToken, params, fullProfile, done) => {
562
- done(void 0, {fullProfile, params, accessToken}, {refreshToken});
581
+ done(void 0, { fullProfile, params, accessToken }, { refreshToken });
563
582
  });
564
583
  }
565
584
  async start(req) {
@@ -569,7 +588,7 @@ class GithubAuthProvider {
569
588
  });
570
589
  }
571
590
  async handler(req) {
572
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
591
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
573
592
  return {
574
593
  response: await this.handleResult(result),
575
594
  refreshToken: privateInfo.refreshToken
@@ -590,7 +609,7 @@ class GithubAuthProvider {
590
609
  });
591
610
  }
592
611
  async handleResult(result) {
593
- const {profile} = await this.authHandler(result);
612
+ const { profile } = await this.authHandler(result);
594
613
  const expiresInStr = result.params.expires_in;
595
614
  const response = {
596
615
  providerInfo: {
@@ -615,12 +634,12 @@ class GithubAuthProvider {
615
634
  }
616
635
  }
617
636
  const githubDefaultSignInResolver = async (info, ctx) => {
618
- const {fullProfile} = info.result;
637
+ const { fullProfile } = info.result;
619
638
  const userId = fullProfile.username || fullProfile.id;
620
639
  const token = await ctx.tokenIssuer.issueToken({
621
- claims: {sub: userId, ent: [`user:default/${userId}`]}
640
+ claims: { sub: userId, ent: [`user:default/${userId}`] }
622
641
  });
623
- return {id: userId, token};
642
+ return { id: userId, token };
624
643
  };
625
644
  const createGithubProvider = (options) => {
626
645
  return ({
@@ -644,7 +663,7 @@ const createGithubProvider = (options) => {
644
663
  catalogApi,
645
664
  tokenIssuer
646
665
  });
647
- const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile}) => ({
666
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
648
667
  profile: makeProfileInfo(fullProfile)
649
668
  });
650
669
  const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : githubDefaultSignInResolver;
@@ -654,7 +673,7 @@ const createGithubProvider = (options) => {
654
673
  logger
655
674
  });
656
675
  const stateEncoder = (_c = options == null ? void 0 : options.stateEncoder) != null ? _c : async (req) => {
657
- return {encodedState: encodeState(req.state)};
676
+ return { encodedState: encodeState(req.state) };
658
677
  };
659
678
  const provider = new GithubAuthProvider({
660
679
  clientId,
@@ -679,15 +698,15 @@ const createGithubProvider = (options) => {
679
698
  };
680
699
 
681
700
  const gitlabDefaultSignInResolver = async (info, ctx) => {
682
- const {profile, result} = info;
701
+ const { profile, result } = info;
683
702
  let id = result.fullProfile.id;
684
703
  if (profile.email) {
685
704
  id = profile.email.split("@")[0];
686
705
  }
687
706
  const token = await ctx.tokenIssuer.issueToken({
688
- claims: {sub: id, ent: [`user:default/${id}`]}
707
+ claims: { sub: id, ent: [`user:default/${id}`] }
689
708
  });
690
- return {id, token};
709
+ return { id, token };
691
710
  };
692
711
  const gitlabDefaultAuthHandler = async ({
693
712
  fullProfile,
@@ -708,7 +727,7 @@ class GitlabAuthProvider {
708
727
  callbackURL: options.callbackUrl,
709
728
  baseURL: options.baseUrl
710
729
  }, (accessToken, refreshToken, params, fullProfile, done) => {
711
- done(void 0, {fullProfile, params, accessToken}, {
730
+ done(void 0, { fullProfile, params, accessToken }, {
712
731
  refreshToken
713
732
  });
714
733
  });
@@ -720,7 +739,7 @@ class GitlabAuthProvider {
720
739
  });
721
740
  }
722
741
  async handler(req) {
723
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
742
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
724
743
  return {
725
744
  response: await this.handleResult(result),
726
745
  refreshToken: privateInfo.refreshToken
@@ -741,7 +760,7 @@ class GitlabAuthProvider {
741
760
  });
742
761
  }
743
762
  async handleResult(result) {
744
- const {profile} = await this.authHandler(result);
763
+ const { profile } = await this.authHandler(result);
745
764
  const response = {
746
765
  providerInfo: {
747
766
  idToken: result.params.id_token,
@@ -842,14 +861,14 @@ class GoogleAuthProvider {
842
861
  });
843
862
  }
844
863
  async handler(req) {
845
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
864
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
846
865
  return {
847
866
  response: await this.handleResult(result),
848
867
  refreshToken: privateInfo.refreshToken
849
868
  };
850
869
  }
851
870
  async refresh(req) {
852
- const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
871
+ const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
853
872
  const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
854
873
  return this.handleResult({
855
874
  fullProfile,
@@ -859,7 +878,7 @@ class GoogleAuthProvider {
859
878
  });
860
879
  }
861
880
  async handleResult(result) {
862
- const {profile} = await this.authHandler(result);
881
+ const { profile } = await this.authHandler(result);
863
882
  const response = {
864
883
  providerInfo: {
865
884
  idToken: result.params.id_token,
@@ -883,7 +902,7 @@ class GoogleAuthProvider {
883
902
  }
884
903
  }
885
904
  const googleEmailSignInResolver = async (info, ctx) => {
886
- const {profile} = info;
905
+ const { profile } = info;
887
906
  if (!profile.email) {
888
907
  throw new Error("Google profile contained no email");
889
908
  }
@@ -893,11 +912,11 @@ const googleEmailSignInResolver = async (info, ctx) => {
893
912
  }
894
913
  });
895
914
  const claims = getEntityClaims(entity);
896
- const token = await ctx.tokenIssuer.issueToken({claims});
897
- return {id: entity.metadata.name, entity, token};
915
+ const token = await ctx.tokenIssuer.issueToken({ claims });
916
+ return { id: entity.metadata.name, entity, token };
898
917
  };
899
918
  const googleDefaultSignInResolver = async (info, ctx) => {
900
- const {profile} = info;
919
+ const { profile } = info;
901
920
  if (!profile.email) {
902
921
  throw new Error("Google profile contained no email");
903
922
  }
@@ -914,9 +933,9 @@ const googleDefaultSignInResolver = async (info, ctx) => {
914
933
  userId = profile.email.split("@")[0];
915
934
  }
916
935
  const token = await ctx.tokenIssuer.issueToken({
917
- claims: {sub: userId, ent: [`user:default/${userId}`]}
936
+ claims: { sub: userId, ent: [`user:default/${userId}`] }
918
937
  });
919
- return {id: userId, token};
938
+ return { id: userId, token };
920
939
  };
921
940
  const createGoogleProvider = (options) => {
922
941
  return ({
@@ -935,7 +954,7 @@ const createGoogleProvider = (options) => {
935
954
  catalogApi,
936
955
  tokenIssuer
937
956
  });
938
- const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
957
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
939
958
  profile: makeProfileInfo(fullProfile, params.id_token)
940
959
  });
941
960
  const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : googleDefaultSignInResolver;
@@ -977,7 +996,7 @@ class MicrosoftAuthProvider {
977
996
  tokenURL: options.tokenUrl,
978
997
  passReqToCallback: false
979
998
  }, (accessToken, refreshToken, params, fullProfile, done) => {
980
- done(void 0, {fullProfile, accessToken, params}, {refreshToken});
999
+ done(void 0, { fullProfile, accessToken, params }, { refreshToken });
981
1000
  });
982
1001
  }
983
1002
  async start(req) {
@@ -987,14 +1006,14 @@ class MicrosoftAuthProvider {
987
1006
  });
988
1007
  }
989
1008
  async handler(req) {
990
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
1009
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
991
1010
  return {
992
1011
  response: await this.handleResult(result),
993
1012
  refreshToken: privateInfo.refreshToken
994
1013
  };
995
1014
  }
996
1015
  async refresh(req) {
997
- const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
1016
+ const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
998
1017
  const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
999
1018
  return this.handleResult({
1000
1019
  fullProfile,
@@ -1005,8 +1024,8 @@ class MicrosoftAuthProvider {
1005
1024
  }
1006
1025
  async handleResult(result) {
1007
1026
  const photo = await this.getUserPhoto(result.accessToken);
1008
- result.fullProfile.photos = photo ? [{value: photo}] : void 0;
1009
- const {profile} = await this.authHandler(result);
1027
+ result.fullProfile.photos = photo ? [{ value: photo }] : void 0;
1028
+ const { profile } = await this.authHandler(result);
1010
1029
  const response = {
1011
1030
  providerInfo: {
1012
1031
  idToken: result.params.id_token,
@@ -1030,7 +1049,7 @@ class MicrosoftAuthProvider {
1030
1049
  }
1031
1050
  getUserPhoto(accessToken) {
1032
1051
  return new Promise((resolve) => {
1033
- got__default['default'].get("https://graph.microsoft.com/v1.0/me/photos/48x48/$value", {
1052
+ got__default["default"].get("https://graph.microsoft.com/v1.0/me/photos/48x48/$value", {
1034
1053
  encoding: "binary",
1035
1054
  responseType: "buffer",
1036
1055
  headers: {
@@ -1047,7 +1066,7 @@ class MicrosoftAuthProvider {
1047
1066
  }
1048
1067
  }
1049
1068
  const microsoftEmailSignInResolver = async (info, ctx) => {
1050
- const {profile} = info;
1069
+ const { profile } = info;
1051
1070
  if (!profile.email) {
1052
1071
  throw new Error("Microsoft profile contained no email");
1053
1072
  }
@@ -1057,19 +1076,19 @@ const microsoftEmailSignInResolver = async (info, ctx) => {
1057
1076
  }
1058
1077
  });
1059
1078
  const claims = getEntityClaims(entity);
1060
- const token = await ctx.tokenIssuer.issueToken({claims});
1061
- return {id: entity.metadata.name, entity, token};
1079
+ const token = await ctx.tokenIssuer.issueToken({ claims });
1080
+ return { id: entity.metadata.name, entity, token };
1062
1081
  };
1063
1082
  const microsoftDefaultSignInResolver = async (info, ctx) => {
1064
- const {profile} = info;
1083
+ const { profile } = info;
1065
1084
  if (!profile.email) {
1066
1085
  throw new Error("Profile contained no email");
1067
1086
  }
1068
1087
  const userId = profile.email.split("@")[0];
1069
1088
  const token = await ctx.tokenIssuer.issueToken({
1070
- claims: {sub: userId, ent: [`user:default/${userId}`]}
1089
+ claims: { sub: userId, ent: [`user:default/${userId}`] }
1071
1090
  });
1072
- return {id: userId, token};
1091
+ return { id: userId, token };
1073
1092
  };
1074
1093
  const createMicrosoftProvider = (options) => {
1075
1094
  return ({
@@ -1091,7 +1110,7 @@ const createMicrosoftProvider = (options) => {
1091
1110
  catalogApi,
1092
1111
  tokenIssuer
1093
1112
  });
1094
- const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
1113
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
1095
1114
  profile: makeProfileInfo(fullProfile, params.id_token)
1096
1115
  });
1097
1116
  const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : microsoftDefaultSignInResolver;
@@ -1134,7 +1153,10 @@ class OAuth2AuthProvider {
1134
1153
  authorizationURL: options.authorizationUrl,
1135
1154
  tokenURL: options.tokenUrl,
1136
1155
  passReqToCallback: false,
1137
- scope: options.scope
1156
+ scope: options.scope,
1157
+ customHeaders: options.includeBasicAuth ? {
1158
+ Authorization: `Basic ${this.encodeClientCredentials(options.clientId, options.clientSecret)}`
1159
+ } : void 0
1138
1160
  }, (accessToken, refreshToken, params, fullProfile, done) => {
1139
1161
  done(void 0, {
1140
1162
  fullProfile,
@@ -1155,7 +1177,7 @@ class OAuth2AuthProvider {
1155
1177
  });
1156
1178
  }
1157
1179
  async handler(req) {
1158
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
1180
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
1159
1181
  return {
1160
1182
  response: await this.handleResult(result),
1161
1183
  refreshToken: privateInfo.refreshToken
@@ -1177,7 +1199,7 @@ class OAuth2AuthProvider {
1177
1199
  });
1178
1200
  }
1179
1201
  async handleResult(result) {
1180
- const {profile} = await this.authHandler(result);
1202
+ const { profile } = await this.authHandler(result);
1181
1203
  const response = {
1182
1204
  providerInfo: {
1183
1205
  idToken: result.params.id_token,
@@ -1200,17 +1222,20 @@ class OAuth2AuthProvider {
1200
1222
  }
1201
1223
  return response;
1202
1224
  }
1225
+ encodeClientCredentials(clientID, clientSecret) {
1226
+ return Buffer.from(`${clientID}:${clientSecret}`).toString("base64");
1227
+ }
1203
1228
  }
1204
- const oAuth2DefaultSignInResolver = async (info, ctx) => {
1205
- const {profile} = info;
1229
+ const oAuth2DefaultSignInResolver$1 = async (info, ctx) => {
1230
+ const { profile } = info;
1206
1231
  if (!profile.email) {
1207
1232
  throw new Error("Profile contained no email");
1208
1233
  }
1209
1234
  const userId = profile.email.split("@")[0];
1210
1235
  const token = await ctx.tokenIssuer.issueToken({
1211
- claims: {sub: userId, ent: [`user:default/${userId}`]}
1236
+ claims: { sub: userId, ent: [`user:default/${userId}`] }
1212
1237
  });
1213
- return {id: userId, token};
1238
+ return { id: userId, token };
1214
1239
  };
1215
1240
  const createOAuth2Provider = (options) => {
1216
1241
  return ({
@@ -1228,15 +1253,16 @@ const createOAuth2Provider = (options) => {
1228
1253
  const authorizationUrl = envConfig.getString("authorizationUrl");
1229
1254
  const tokenUrl = envConfig.getString("tokenUrl");
1230
1255
  const scope = envConfig.getOptionalString("scope");
1256
+ const includeBasicAuth = envConfig.getOptionalBoolean("includeBasicAuth");
1231
1257
  const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
1232
1258
  const catalogIdentityClient = new CatalogIdentityClient({
1233
1259
  catalogApi,
1234
1260
  tokenIssuer
1235
1261
  });
1236
- const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
1262
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
1237
1263
  profile: makeProfileInfo(fullProfile, params.id_token)
1238
1264
  });
1239
- const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver;
1265
+ const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver$1;
1240
1266
  const signInResolver = (info) => signInResolverFn(info, {
1241
1267
  catalogIdentityClient,
1242
1268
  tokenIssuer,
@@ -1253,7 +1279,8 @@ const createOAuth2Provider = (options) => {
1253
1279
  authorizationUrl,
1254
1280
  tokenUrl,
1255
1281
  scope,
1256
- logger
1282
+ logger,
1283
+ includeBasicAuth
1257
1284
  });
1258
1285
  return OAuthAdapter.fromConfig(globalConfig, provider, {
1259
1286
  disableRefresh,
@@ -1263,6 +1290,168 @@ const createOAuth2Provider = (options) => {
1263
1290
  });
1264
1291
  };
1265
1292
 
1293
+ class OidcAuthProvider {
1294
+ constructor(options) {
1295
+ this.implementation = this.setupStrategy(options);
1296
+ this.scope = options.scope;
1297
+ this.prompt = options.prompt;
1298
+ this.signInResolver = options.signInResolver;
1299
+ this.authHandler = options.authHandler;
1300
+ this.tokenIssuer = options.tokenIssuer;
1301
+ this.catalogIdentityClient = options.catalogIdentityClient;
1302
+ this.logger = options.logger;
1303
+ }
1304
+ async start(req) {
1305
+ const { strategy } = await this.implementation;
1306
+ const options = {
1307
+ scope: req.scope || this.scope || "openid profile email",
1308
+ state: encodeState(req.state)
1309
+ };
1310
+ const prompt = this.prompt || "none";
1311
+ if (prompt !== "auto") {
1312
+ options.prompt = prompt;
1313
+ }
1314
+ return await executeRedirectStrategy(req, strategy, options);
1315
+ }
1316
+ async handler(req) {
1317
+ const { strategy } = await this.implementation;
1318
+ const strategyResponse = await executeFrameHandlerStrategy(req, strategy);
1319
+ const {
1320
+ result: { userinfo, tokenset },
1321
+ privateInfo
1322
+ } = strategyResponse;
1323
+ const identityResponse = await this.handleResult({ tokenset, userinfo });
1324
+ return {
1325
+ response: identityResponse,
1326
+ refreshToken: privateInfo.refreshToken
1327
+ };
1328
+ }
1329
+ async refresh(req) {
1330
+ const { client } = await this.implementation;
1331
+ const tokenset = await client.refresh(req.refreshToken);
1332
+ if (!tokenset.access_token) {
1333
+ throw new Error("Refresh failed");
1334
+ }
1335
+ const profile = await client.userinfo(tokenset.access_token);
1336
+ return this.handleResult({ tokenset, userinfo: profile });
1337
+ }
1338
+ async setupStrategy(options) {
1339
+ const issuer = await openidClient.Issuer.discover(options.metadataUrl);
1340
+ const client = new issuer.Client({
1341
+ access_type: "offline",
1342
+ client_id: options.clientId,
1343
+ client_secret: options.clientSecret,
1344
+ redirect_uris: [options.callbackUrl],
1345
+ response_types: ["code"],
1346
+ id_token_signed_response_alg: options.tokenSignedResponseAlg || "RS256",
1347
+ scope: options.scope || ""
1348
+ });
1349
+ const strategy = new openidClient.Strategy({
1350
+ client,
1351
+ passReqToCallback: false
1352
+ }, (tokenset, userinfo, done) => {
1353
+ if (typeof done !== "function") {
1354
+ throw new Error("OIDC IdP must provide a userinfo_endpoint in the metadata response");
1355
+ }
1356
+ done(void 0, { tokenset, userinfo }, {
1357
+ refreshToken: tokenset.refresh_token
1358
+ });
1359
+ });
1360
+ strategy.error = console.error;
1361
+ return { strategy, client };
1362
+ }
1363
+ async handleResult(result) {
1364
+ const { profile } = await this.authHandler(result);
1365
+ const response = {
1366
+ providerInfo: {
1367
+ idToken: result.tokenset.id_token,
1368
+ accessToken: result.tokenset.access_token,
1369
+ refreshToken: result.tokenset.refresh_token,
1370
+ scope: result.tokenset.scope,
1371
+ expiresInSeconds: result.tokenset.expires_in
1372
+ },
1373
+ profile
1374
+ };
1375
+ if (this.signInResolver) {
1376
+ response.backstageIdentity = await this.signInResolver({
1377
+ result,
1378
+ profile
1379
+ }, {
1380
+ tokenIssuer: this.tokenIssuer,
1381
+ catalogIdentityClient: this.catalogIdentityClient,
1382
+ logger: this.logger
1383
+ });
1384
+ }
1385
+ return response;
1386
+ }
1387
+ }
1388
+ const oAuth2DefaultSignInResolver = async (info, ctx) => {
1389
+ const { profile } = info;
1390
+ if (!profile.email) {
1391
+ throw new Error("Profile contained no email");
1392
+ }
1393
+ const userId = profile.email.split("@")[0];
1394
+ const token = await ctx.tokenIssuer.issueToken({
1395
+ claims: { sub: userId, ent: [`user:default/${userId}`] }
1396
+ });
1397
+ return { id: userId, token };
1398
+ };
1399
+ const createOidcProvider = (options) => {
1400
+ return ({
1401
+ providerId,
1402
+ globalConfig,
1403
+ config,
1404
+ tokenIssuer,
1405
+ catalogApi,
1406
+ logger
1407
+ }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
1408
+ var _a, _b;
1409
+ const clientId = envConfig.getString("clientId");
1410
+ const clientSecret = envConfig.getString("clientSecret");
1411
+ const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1412
+ const metadataUrl = envConfig.getString("metadataUrl");
1413
+ const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
1414
+ const scope = envConfig.getOptionalString("scope");
1415
+ const prompt = envConfig.getOptionalString("prompt");
1416
+ const catalogIdentityClient = new CatalogIdentityClient({
1417
+ catalogApi,
1418
+ tokenIssuer
1419
+ });
1420
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
1421
+ profile: {
1422
+ displayName: userinfo.name,
1423
+ email: userinfo.email,
1424
+ picture: userinfo.picture
1425
+ }
1426
+ });
1427
+ const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oAuth2DefaultSignInResolver;
1428
+ const signInResolver = (info) => signInResolverFn(info, {
1429
+ catalogIdentityClient,
1430
+ tokenIssuer,
1431
+ logger
1432
+ });
1433
+ const provider = new OidcAuthProvider({
1434
+ clientId,
1435
+ clientSecret,
1436
+ callbackUrl,
1437
+ tokenSignedResponseAlg,
1438
+ metadataUrl,
1439
+ scope,
1440
+ prompt,
1441
+ signInResolver,
1442
+ authHandler,
1443
+ logger,
1444
+ tokenIssuer,
1445
+ catalogIdentityClient
1446
+ });
1447
+ return OAuthAdapter.fromConfig(globalConfig, provider, {
1448
+ disableRefresh: false,
1449
+ providerId,
1450
+ tokenIssuer
1451
+ });
1452
+ });
1453
+ };
1454
+
1266
1455
  class OktaAuthProvider {
1267
1456
  constructor(options) {
1268
1457
  this._store = {
@@ -1306,14 +1495,14 @@ class OktaAuthProvider {
1306
1495
  });
1307
1496
  }
1308
1497
  async handler(req) {
1309
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
1498
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
1310
1499
  return {
1311
1500
  response: await this.handleResult(result),
1312
1501
  refreshToken: privateInfo.refreshToken
1313
1502
  };
1314
1503
  }
1315
1504
  async refresh(req) {
1316
- const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
1505
+ const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
1317
1506
  const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
1318
1507
  return this.handleResult({
1319
1508
  fullProfile,
@@ -1323,7 +1512,7 @@ class OktaAuthProvider {
1323
1512
  });
1324
1513
  }
1325
1514
  async handleResult(result) {
1326
- const {profile} = await this._authHandler(result);
1515
+ const { profile } = await this._authHandler(result);
1327
1516
  const response = {
1328
1517
  providerInfo: {
1329
1518
  idToken: result.params.id_token,
@@ -1347,7 +1536,7 @@ class OktaAuthProvider {
1347
1536
  }
1348
1537
  }
1349
1538
  const oktaEmailSignInResolver = async (info, ctx) => {
1350
- const {profile} = info;
1539
+ const { profile } = info;
1351
1540
  if (!profile.email) {
1352
1541
  throw new Error("Okta profile contained no email");
1353
1542
  }
@@ -1357,19 +1546,19 @@ const oktaEmailSignInResolver = async (info, ctx) => {
1357
1546
  }
1358
1547
  });
1359
1548
  const claims = getEntityClaims(entity);
1360
- const token = await ctx.tokenIssuer.issueToken({claims});
1361
- return {id: entity.metadata.name, entity, token};
1549
+ const token = await ctx.tokenIssuer.issueToken({ claims });
1550
+ return { id: entity.metadata.name, entity, token };
1362
1551
  };
1363
1552
  const oktaDefaultSignInResolver = async (info, ctx) => {
1364
- const {profile} = info;
1553
+ const { profile } = info;
1365
1554
  if (!profile.email) {
1366
1555
  throw new Error("Okta profile contained no email");
1367
1556
  }
1368
1557
  const userId = profile.email.split("@")[0];
1369
1558
  const token = await ctx.tokenIssuer.issueToken({
1370
- claims: {sub: userId, ent: [`user:default/${userId}`]}
1559
+ claims: { sub: userId, ent: [`user:default/${userId}`] }
1371
1560
  });
1372
- return {id: userId, token};
1561
+ return { id: userId, token };
1373
1562
  };
1374
1563
  const createOktaProvider = (_options) => {
1375
1564
  return ({
@@ -1392,7 +1581,7 @@ const createOktaProvider = (_options) => {
1392
1581
  catalogApi,
1393
1582
  tokenIssuer
1394
1583
  });
1395
- const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({fullProfile, params}) => ({
1584
+ const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({ fullProfile, params }) => ({
1396
1585
  profile: makeProfileInfo(fullProfile, params.id_token)
1397
1586
  });
1398
1587
  const signInResolverFn = (_b = (_a = _options == null ? void 0 : _options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oktaDefaultSignInResolver;
@@ -1452,14 +1641,14 @@ class BitbucketAuthProvider {
1452
1641
  });
1453
1642
  }
1454
1643
  async handler(req) {
1455
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
1644
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
1456
1645
  return {
1457
1646
  response: await this.handleResult(result),
1458
1647
  refreshToken: privateInfo.refreshToken
1459
1648
  };
1460
1649
  }
1461
1650
  async refresh(req) {
1462
- const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
1651
+ const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
1463
1652
  const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
1464
1653
  return this.handleResult({
1465
1654
  fullProfile,
@@ -1470,7 +1659,7 @@ class BitbucketAuthProvider {
1470
1659
  }
1471
1660
  async handleResult(result) {
1472
1661
  result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
1473
- const {profile} = await this.authHandler(result);
1662
+ const { profile } = await this.authHandler(result);
1474
1663
  const response = {
1475
1664
  providerInfo: {
1476
1665
  idToken: result.params.id_token,
@@ -1494,7 +1683,7 @@ class BitbucketAuthProvider {
1494
1683
  }
1495
1684
  }
1496
1685
  const bitbucketUsernameSignInResolver = async (info, ctx) => {
1497
- const {result} = info;
1686
+ const { result } = info;
1498
1687
  if (!result.fullProfile.username) {
1499
1688
  throw new Error("Bitbucket profile contained no Username");
1500
1689
  }
@@ -1504,11 +1693,11 @@ const bitbucketUsernameSignInResolver = async (info, ctx) => {
1504
1693
  }
1505
1694
  });
1506
1695
  const claims = getEntityClaims(entity);
1507
- const token = await ctx.tokenIssuer.issueToken({claims});
1508
- return {id: entity.metadata.name, entity, token};
1696
+ const token = await ctx.tokenIssuer.issueToken({ claims });
1697
+ return { id: entity.metadata.name, entity, token };
1509
1698
  };
1510
1699
  const bitbucketUserIdSignInResolver = async (info, ctx) => {
1511
- const {result} = info;
1700
+ const { result } = info;
1512
1701
  if (!result.fullProfile.id) {
1513
1702
  throw new Error("Bitbucket profile contained no User ID");
1514
1703
  }
@@ -1518,8 +1707,8 @@ const bitbucketUserIdSignInResolver = async (info, ctx) => {
1518
1707
  }
1519
1708
  });
1520
1709
  const claims = getEntityClaims(entity);
1521
- const token = await ctx.tokenIssuer.issueToken({claims});
1522
- return {id: entity.metadata.name, entity, token};
1710
+ const token = await ctx.tokenIssuer.issueToken({ claims });
1711
+ return { id: entity.metadata.name, entity, token };
1523
1712
  };
1524
1713
  const createBitbucketProvider = (options) => {
1525
1714
  return ({
@@ -1538,7 +1727,7 @@ const createBitbucketProvider = (options) => {
1538
1727
  catalogApi,
1539
1728
  tokenIssuer
1540
1729
  });
1541
- const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
1730
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
1542
1731
  profile: makeProfileInfo(fullProfile, params.id_token)
1543
1732
  });
1544
1733
  const provider = new BitbucketAuthProvider({
@@ -1560,7 +1749,7 @@ const createBitbucketProvider = (options) => {
1560
1749
  };
1561
1750
 
1562
1751
  const defaultScopes = ["offline_access", "read:me"];
1563
- class AtlassianStrategy extends OAuth2Strategy__default['default'] {
1752
+ class AtlassianStrategy extends OAuth2Strategy__default["default"] {
1564
1753
  constructor(options, verify) {
1565
1754
  if (!options.scope) {
1566
1755
  throw new TypeError("Atlassian requires a scope option");
@@ -1570,7 +1759,7 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
1570
1759
  ...options,
1571
1760
  authorizationURL: `https://auth.atlassian.com/authorize`,
1572
1761
  tokenURL: `https://auth.atlassian.com/oauth/token`,
1573
- scope: Array.from(new Set([...defaultScopes, ...scopes]))
1762
+ scope: Array.from(/* @__PURE__ */ new Set([...defaultScopes, ...scopes]))
1574
1763
  };
1575
1764
  super(optionsWithURLs, verify);
1576
1765
  this.profileURL = "https://api.atlassian.com/me";
@@ -1607,8 +1796,8 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
1607
1796
  provider: "atlassian",
1608
1797
  username: resp.nickname,
1609
1798
  displayName: resp.name,
1610
- emails: [{value: resp.email}],
1611
- photos: [{value: resp.picture}]
1799
+ emails: [{ value: resp.email }],
1800
+ photos: [{ value: resp.picture }]
1612
1801
  };
1613
1802
  }
1614
1803
  }
@@ -1647,14 +1836,14 @@ class AtlassianAuthProvider {
1647
1836
  }
1648
1837
  async handler(req) {
1649
1838
  var _a;
1650
- const {result} = await executeFrameHandlerStrategy(req, this._strategy);
1839
+ const { result } = await executeFrameHandlerStrategy(req, this._strategy);
1651
1840
  return {
1652
1841
  response: await this.handleResult(result),
1653
1842
  refreshToken: (_a = result.refreshToken) != null ? _a : ""
1654
1843
  };
1655
1844
  }
1656
1845
  async handleResult(result) {
1657
- const {profile} = await this.authHandler(result);
1846
+ const { profile } = await this.authHandler(result);
1658
1847
  const response = {
1659
1848
  providerInfo: {
1660
1849
  idToken: result.params.id_token,
@@ -1745,7 +1934,7 @@ class AwsAlbAuthProvider {
1745
1934
  this.tokenIssuer = options.tokenIssuer;
1746
1935
  this.catalogIdentityClient = options.catalogIdentityClient;
1747
1936
  this.logger = options.logger;
1748
- this.keyCache = new NodeCache__default['default']({stdTTL: 3600});
1937
+ this.keyCache = new NodeCache__default["default"]({ stdTTL: 3600 });
1749
1938
  }
1750
1939
  frameHandler() {
1751
1940
  return Promise.resolve(void 0);
@@ -1789,8 +1978,8 @@ class AwsAlbAuthProvider {
1789
1978
  familyName: claims.family_name,
1790
1979
  givenName: claims.given_name
1791
1980
  },
1792
- emails: [{value: claims.email.toLowerCase()}],
1793
- photos: [{value: claims.picture}]
1981
+ emails: [{ value: claims.email.toLowerCase() }],
1982
+ photos: [{ value: claims.picture }]
1794
1983
  };
1795
1984
  return {
1796
1985
  fullProfile,
@@ -1802,7 +1991,7 @@ class AwsAlbAuthProvider {
1802
1991
  }
1803
1992
  }
1804
1993
  async handleResult(result) {
1805
- const {profile} = await this.authHandler(result);
1994
+ const { profile } = await this.authHandler(result);
1806
1995
  const backstageIdentity = await this.signInResolver({
1807
1996
  result,
1808
1997
  profile
@@ -1816,7 +2005,7 @@ class AwsAlbAuthProvider {
1816
2005
  accessToken: result.accessToken,
1817
2006
  expiresInSeconds: result.expiresInSeconds
1818
2007
  },
1819
- backstageIdentity,
2008
+ backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
1820
2009
  profile
1821
2010
  };
1822
2011
  }
@@ -1825,14 +2014,14 @@ class AwsAlbAuthProvider {
1825
2014
  if (optionalCacheKey) {
1826
2015
  return crypto__namespace.createPublicKey(optionalCacheKey);
1827
2016
  }
1828
- const keyText = await fetch__default['default'](`https://public-keys.auth.elb.${this.region}.amazonaws.com/${keyId}`).then((response) => response.text());
2017
+ const keyText = await fetch__default["default"](`https://public-keys.auth.elb.${this.region}.amazonaws.com/${keyId}`).then((response) => response.text());
1829
2018
  const keyValue = crypto__namespace.createPublicKey(keyText);
1830
- this.keyCache.set(keyId, keyValue.export({format: "pem", type: "spki"}));
2019
+ this.keyCache.set(keyId, keyValue.export({ format: "pem", type: "spki" }));
1831
2020
  return keyValue;
1832
2021
  }
1833
2022
  }
1834
2023
  const createAwsAlbProvider = (options) => {
1835
- return ({config, tokenIssuer, catalogApi, logger}) => {
2024
+ return ({ config, tokenIssuer, catalogApi, logger }) => {
1836
2025
  const region = config.getString("region");
1837
2026
  const issuer = config.getOptionalString("iss");
1838
2027
  if ((options == null ? void 0 : options.signIn.resolver) === void 0) {
@@ -1842,7 +2031,7 @@ const createAwsAlbProvider = (options) => {
1842
2031
  catalogApi,
1843
2032
  tokenIssuer
1844
2033
  });
1845
- const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile}) => ({
2034
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
1846
2035
  profile: makeProfileInfo(fullProfile)
1847
2036
  });
1848
2037
  const signInResolver = options == null ? void 0 : options.signIn.resolver;
@@ -1858,182 +2047,98 @@ const createAwsAlbProvider = (options) => {
1858
2047
  };
1859
2048
  };
1860
2049
 
1861
- class OidcAuthProvider {
1862
- constructor(options) {
1863
- this.implementation = this.setupStrategy(options);
1864
- this.scope = options.scope;
1865
- this.prompt = options.prompt;
1866
- }
1867
- async start(req) {
1868
- const {strategy} = await this.implementation;
1869
- const options = {
1870
- accessType: "offline",
1871
- scope: req.scope || this.scope || "openid profile email",
1872
- state: encodeState(req.state)
1873
- };
1874
- const prompt = this.prompt || "none";
1875
- if (prompt !== "auto") {
1876
- options.prompt = prompt;
1877
- }
1878
- return await executeRedirectStrategy(req, strategy, options);
1879
- }
1880
- async handler(req) {
1881
- const {strategy} = await this.implementation;
1882
- const strategyResponse = await executeFrameHandlerStrategy(req, strategy);
1883
- const {
1884
- result: {userinfo, tokenset},
1885
- privateInfo
1886
- } = strategyResponse;
1887
- const identityResponse = await this.populateIdentity({
1888
- profile: {
1889
- displayName: userinfo.name,
1890
- email: userinfo.email,
1891
- picture: userinfo.picture
1892
- },
1893
- providerInfo: {
1894
- idToken: tokenset.id_token,
1895
- accessToken: tokenset.access_token || "",
1896
- scope: tokenset.scope || "",
1897
- expiresInSeconds: tokenset.expires_in
1898
- }
1899
- });
1900
- return {
1901
- response: identityResponse,
1902
- refreshToken: privateInfo.refreshToken
1903
- };
1904
- }
1905
- async refresh(req) {
1906
- const {client} = await this.implementation;
1907
- const tokenset = await client.refresh(req.refreshToken);
1908
- if (!tokenset.access_token) {
1909
- throw new Error("Refresh failed");
1910
- }
1911
- const profile = await client.userinfo(tokenset.access_token);
1912
- return this.populateIdentity({
1913
- providerInfo: {
1914
- accessToken: tokenset.access_token,
1915
- refreshToken: tokenset.refresh_token,
1916
- expiresInSeconds: tokenset.expires_in,
1917
- idToken: tokenset.id_token,
1918
- scope: tokenset.scope || ""
1919
- },
1920
- profile
1921
- });
1922
- }
1923
- async setupStrategy(options) {
1924
- const issuer = await openidClient.Issuer.discover(options.metadataUrl);
1925
- const client = new issuer.Client({
1926
- client_id: options.clientId,
1927
- client_secret: options.clientSecret,
1928
- redirect_uris: [options.callbackUrl],
1929
- response_types: ["code"],
1930
- id_token_signed_response_alg: options.tokenSignedResponseAlg || "RS256",
1931
- scope: options.scope || ""
1932
- });
1933
- const strategy = new openidClient.Strategy({
1934
- client,
1935
- passReqToCallback: false
1936
- }, (tokenset, userinfo, done) => {
1937
- if (typeof done !== "function") {
1938
- throw new Error("OIDC IdP must provide a userinfo_endpoint in the metadata response");
1939
- }
1940
- done(void 0, {tokenset, userinfo}, {
1941
- refreshToken: tokenset.refresh_token
1942
- });
1943
- });
1944
- strategy.error = console.error;
1945
- return {strategy, client};
1946
- }
1947
- async populateIdentity(response) {
1948
- const {profile} = response;
1949
- if (!profile.email) {
1950
- throw new Error("Profile does not contain an email");
1951
- }
1952
- const id = profile.email.split("@")[0];
1953
- return {...response, backstageIdentity: {id}};
1954
- }
1955
- }
1956
- const createOidcProvider = (_options) => {
1957
- return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
1958
- const clientId = envConfig.getString("clientId");
1959
- const clientSecret = envConfig.getString("clientSecret");
1960
- const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
1961
- const metadataUrl = envConfig.getString("metadataUrl");
1962
- const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
1963
- const scope = envConfig.getOptionalString("scope");
1964
- const prompt = envConfig.getOptionalString("prompt");
1965
- const provider = new OidcAuthProvider({
1966
- clientId,
1967
- clientSecret,
1968
- callbackUrl,
1969
- tokenSignedResponseAlg,
1970
- metadataUrl,
1971
- scope,
1972
- prompt
1973
- });
1974
- return OAuthAdapter.fromConfig(globalConfig, provider, {
1975
- disableRefresh: false,
1976
- providerId,
1977
- tokenIssuer
1978
- });
1979
- });
1980
- };
1981
-
1982
2050
  class SamlAuthProvider {
1983
2051
  constructor(options) {
1984
2052
  this.appUrl = options.appUrl;
2053
+ this.signInResolver = options.signInResolver;
2054
+ this.authHandler = options.authHandler;
1985
2055
  this.tokenIssuer = options.tokenIssuer;
1986
- this.strategy = new passportSaml.Strategy({...options}, (fullProfile, done) => {
1987
- done(void 0, {fullProfile});
2056
+ this.catalogIdentityClient = options.catalogIdentityClient;
2057
+ this.logger = options.logger;
2058
+ this.strategy = new passportSaml.Strategy({ ...options }, (fullProfile, done) => {
2059
+ done(void 0, { fullProfile });
1988
2060
  });
1989
2061
  }
1990
2062
  async start(req, res) {
1991
- const {url} = await executeRedirectStrategy(req, this.strategy, {});
2063
+ const { url } = await executeRedirectStrategy(req, this.strategy, {});
1992
2064
  res.redirect(url);
1993
2065
  }
1994
2066
  async frameHandler(req, res) {
1995
2067
  try {
1996
- const {result} = await executeFrameHandlerStrategy(req, this.strategy);
1997
- const id = result.fullProfile.nameID;
1998
- const idToken = await this.tokenIssuer.issueToken({
1999
- claims: {sub: id}
2000
- });
2068
+ const { result } = await executeFrameHandlerStrategy(req, this.strategy);
2069
+ const { profile } = await this.authHandler(result);
2070
+ const response = {
2071
+ profile,
2072
+ providerInfo: {}
2073
+ };
2074
+ if (this.signInResolver) {
2075
+ const signInResponse = await this.signInResolver({
2076
+ result,
2077
+ profile
2078
+ }, {
2079
+ tokenIssuer: this.tokenIssuer,
2080
+ catalogIdentityClient: this.catalogIdentityClient,
2081
+ logger: this.logger
2082
+ });
2083
+ response.backstageIdentity = prepareBackstageIdentityResponse(signInResponse);
2084
+ }
2001
2085
  return postMessageResponse(res, this.appUrl, {
2002
2086
  type: "authorization_response",
2003
- response: {
2004
- profile: {
2005
- email: result.fullProfile.email,
2006
- displayName: result.fullProfile.displayName
2007
- },
2008
- providerInfo: {},
2009
- backstageIdentity: {id, idToken}
2010
- }
2087
+ response
2011
2088
  });
2012
2089
  } catch (error) {
2013
- const {name, message} = errors.isError(error) ? error : new Error("Encountered invalid error");
2090
+ const { name, message } = errors.isError(error) ? error : new Error("Encountered invalid error");
2014
2091
  return postMessageResponse(res, this.appUrl, {
2015
2092
  type: "authorization_response",
2016
- error: {name, message}
2093
+ error: { name, message }
2017
2094
  });
2018
2095
  }
2019
2096
  }
2020
2097
  async logout(_req, res) {
2021
- res.send("noop");
2022
- }
2023
- identifyEnv() {
2024
- return void 0;
2098
+ res.end();
2025
2099
  }
2026
2100
  }
2027
- const createSamlProvider = (_options) => {
2028
- return ({providerId, globalConfig, config, tokenIssuer}) => {
2029
- const opts = {
2101
+ const samlDefaultSignInResolver = async (info, ctx) => {
2102
+ const id = info.result.fullProfile.nameID;
2103
+ const token = await ctx.tokenIssuer.issueToken({
2104
+ claims: { sub: id }
2105
+ });
2106
+ return { id, token };
2107
+ };
2108
+ const createSamlProvider = (options) => {
2109
+ return ({
2110
+ providerId,
2111
+ globalConfig,
2112
+ config,
2113
+ tokenIssuer,
2114
+ catalogApi,
2115
+ logger
2116
+ }) => {
2117
+ var _a, _b;
2118
+ const catalogIdentityClient = new CatalogIdentityClient({
2119
+ catalogApi,
2120
+ tokenIssuer
2121
+ });
2122
+ const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
2123
+ profile: {
2124
+ email: fullProfile.email,
2125
+ displayName: fullProfile.displayName
2126
+ }
2127
+ });
2128
+ const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : samlDefaultSignInResolver;
2129
+ const signInResolver = (info) => signInResolverFn(info, {
2130
+ catalogIdentityClient,
2131
+ tokenIssuer,
2132
+ logger
2133
+ });
2134
+ return new SamlAuthProvider({
2030
2135
  callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
2031
2136
  entryPoint: config.getString("entryPoint"),
2032
2137
  logoutUrl: config.getOptionalString("logoutUrl"),
2033
2138
  audience: config.getOptionalString("audience"),
2034
2139
  issuer: config.getString("issuer"),
2035
2140
  cert: config.getString("cert"),
2036
- privateCert: config.getOptionalString("privateKey"),
2141
+ privateKey: config.getOptionalString("privateKey"),
2037
2142
  authnContext: config.getOptionalStringArray("authnContext"),
2038
2143
  identifierFormat: config.getOptionalString("identifierFormat"),
2039
2144
  decryptionPvk: config.getOptionalString("decryptionPvk"),
@@ -2041,13 +2146,16 @@ const createSamlProvider = (_options) => {
2041
2146
  digestAlgorithm: config.getOptionalString("digestAlgorithm"),
2042
2147
  acceptedClockSkewMs: config.getOptionalNumber("acceptedClockSkewMs"),
2043
2148
  tokenIssuer,
2044
- appUrl: globalConfig.appUrl
2045
- };
2046
- return new SamlAuthProvider(opts);
2149
+ appUrl: globalConfig.appUrl,
2150
+ authHandler,
2151
+ signInResolver,
2152
+ logger,
2153
+ catalogIdentityClient
2154
+ });
2047
2155
  };
2048
2156
  };
2049
2157
 
2050
- class Auth0Strategy extends OAuth2Strategy__default['default'] {
2158
+ class Auth0Strategy extends OAuth2Strategy__default["default"] {
2051
2159
  constructor(options, verify) {
2052
2160
  const optionsWithURLs = {
2053
2161
  ...options,
@@ -2088,7 +2196,7 @@ class Auth0AuthProvider {
2088
2196
  });
2089
2197
  }
2090
2198
  async handler(req) {
2091
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
2199
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
2092
2200
  const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
2093
2201
  return {
2094
2202
  response: await this.populateIdentity({
@@ -2104,7 +2212,7 @@ class Auth0AuthProvider {
2104
2212
  };
2105
2213
  }
2106
2214
  async refresh(req) {
2107
- const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
2215
+ const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
2108
2216
  const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
2109
2217
  const profile = makeProfileInfo(fullProfile, params.id_token);
2110
2218
  return this.populateIdentity({
@@ -2118,16 +2226,16 @@ class Auth0AuthProvider {
2118
2226
  });
2119
2227
  }
2120
2228
  async populateIdentity(response) {
2121
- const {profile} = response;
2229
+ const { profile } = response;
2122
2230
  if (!profile.email) {
2123
2231
  throw new Error("Profile does not contain an email");
2124
2232
  }
2125
2233
  const id = profile.email.split("@")[0];
2126
- return {...response, backstageIdentity: {id}};
2234
+ return { ...response, backstageIdentity: { id, token: "" } };
2127
2235
  }
2128
2236
  }
2129
2237
  const createAuth0Provider = (_options) => {
2130
- return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
2238
+ return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
2131
2239
  const clientId = envConfig.getString("clientId");
2132
2240
  const clientSecret = envConfig.getString("clientSecret");
2133
2241
  const domain = envConfig.getString("domain");
@@ -2174,7 +2282,7 @@ class OneLoginProvider {
2174
2282
  });
2175
2283
  }
2176
2284
  async handler(req) {
2177
- const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
2285
+ const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
2178
2286
  const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
2179
2287
  return {
2180
2288
  response: await this.populateIdentity({
@@ -2190,7 +2298,7 @@ class OneLoginProvider {
2190
2298
  };
2191
2299
  }
2192
2300
  async refresh(req) {
2193
- const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
2301
+ const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
2194
2302
  const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
2195
2303
  const profile = makeProfileInfo(fullProfile, params.id_token);
2196
2304
  return this.populateIdentity({
@@ -2204,16 +2312,16 @@ class OneLoginProvider {
2204
2312
  });
2205
2313
  }
2206
2314
  async populateIdentity(response) {
2207
- const {profile} = response;
2315
+ const { profile } = response;
2208
2316
  if (!profile.email) {
2209
2317
  throw new Error("OIDC profile contained no email");
2210
2318
  }
2211
2319
  const id = profile.email.split("@")[0];
2212
- return {...response, backstageIdentity: {id}};
2320
+ return { ...response, backstageIdentity: { id, token: "" } };
2213
2321
  }
2214
2322
  }
2215
2323
  const createOneLoginProvider = (_options) => {
2216
- return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
2324
+ return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
2217
2325
  const clientId = envConfig.getString("clientId");
2218
2326
  const clientSecret = envConfig.getString("clientSecret");
2219
2327
  const issuer = envConfig.getString("issuer");
@@ -2249,8 +2357,8 @@ const factories = {
2249
2357
  };
2250
2358
 
2251
2359
  function createOidcRouter(options) {
2252
- const {baseUrl, tokenIssuer} = options;
2253
- const router = Router__default['default']();
2360
+ const { baseUrl, tokenIssuer } = options;
2361
+ const router = Router__default["default"]();
2254
2362
  const config = {
2255
2363
  issuer: baseUrl,
2256
2364
  token_endpoint: `${baseUrl}/v1/token`,
@@ -2268,8 +2376,8 @@ function createOidcRouter(options) {
2268
2376
  res.json(config);
2269
2377
  });
2270
2378
  router.get("/.well-known/jwks.json", async (_req, res) => {
2271
- const {keys} = await tokenIssuer.listPublicKeys();
2272
- res.json({keys});
2379
+ const { keys } = await tokenIssuer.listPublicKeys();
2380
+ res.json({ keys });
2273
2381
  });
2274
2382
  router.get("/v1/token", (_req, res) => {
2275
2383
  res.status(501).send("Not Implemented");
@@ -2289,21 +2397,30 @@ class IdentityClient {
2289
2397
  this.keyStoreUpdated = 0;
2290
2398
  }
2291
2399
  async authenticate(token) {
2400
+ var _a;
2292
2401
  if (!token) {
2293
- throw new Error("No token specified");
2402
+ throw new errors.AuthenticationError("No token specified");
2294
2403
  }
2295
2404
  const key = await this.getKey(token);
2296
2405
  if (!key) {
2297
- throw new Error("No signing key matching token found");
2406
+ throw new errors.AuthenticationError("No signing key matching token found");
2298
2407
  }
2299
2408
  const decoded = jose.JWT.IdToken.verify(token, key, {
2300
2409
  algorithms: ["ES256"],
2301
2410
  audience: "backstage",
2302
2411
  issuer: this.issuer
2303
2412
  });
2413
+ if (!decoded.sub) {
2414
+ throw new errors.AuthenticationError("No user sub found in token");
2415
+ }
2304
2416
  const user = {
2305
2417
  id: decoded.sub,
2306
- idToken: token
2418
+ token,
2419
+ identity: {
2420
+ type: "user",
2421
+ userEntityRef: decoded.sub,
2422
+ ownershipEntityRefs: (_a = decoded.ent) != null ? _a : []
2423
+ }
2307
2424
  };
2308
2425
  return user;
2309
2426
  }
@@ -2315,19 +2432,19 @@ class IdentityClient {
2315
2432
  return matches == null ? void 0 : matches[1];
2316
2433
  }
2317
2434
  async getKey(rawJwtToken) {
2318
- const {header, payload} = jose.JWT.decode(rawJwtToken, {
2435
+ const { header, payload } = jose.JWT.decode(rawJwtToken, {
2319
2436
  complete: true
2320
2437
  });
2321
- const keyStoreHasKey = !!this.keyStore.get({kid: header.kid});
2438
+ const keyStoreHasKey = !!this.keyStore.get({ kid: header.kid });
2322
2439
  const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > this.keyStoreUpdated - CLOCK_MARGIN_S;
2323
2440
  if (!keyStoreHasKey && issuedAfterLastRefresh) {
2324
2441
  await this.refreshKeyStore();
2325
2442
  }
2326
- return this.keyStore.get({kid: header.kid});
2443
+ return this.keyStore.get({ kid: header.kid });
2327
2444
  }
2328
2445
  async listPublicKeys() {
2329
2446
  const url = `${await this.discovery.getBaseUrl("auth")}/.well-known/jwks.json`;
2330
- const response = await fetch__default['default'](url);
2447
+ const response = await fetch__default["default"](url);
2331
2448
  if (!response.ok) {
2332
2449
  const payload = await response.text();
2333
2450
  const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`;
@@ -2363,13 +2480,13 @@ class TokenFactory {
2363
2480
  const iat = Math.floor(Date.now() / MS_IN_S);
2364
2481
  const exp = iat + this.keyDurationSeconds;
2365
2482
  this.logger.info(`Issuing token for ${sub}, with entities ${ent != null ? ent : []}`);
2366
- return jose.JWS.sign({iss, sub, aud, iat, exp, ent}, key, {
2483
+ return jose.JWS.sign({ iss, sub, aud, iat, exp, ent }, key, {
2367
2484
  alg: key.alg,
2368
2485
  kid: key.kid
2369
2486
  });
2370
2487
  }
2371
2488
  async listPublicKeys() {
2372
- const {items: keys} = await this.keyStore.listKeys();
2489
+ const { items: keys } = await this.keyStore.listKeys();
2373
2490
  const validKeys = [];
2374
2491
  const expiredKeys = [];
2375
2492
  for (const key of keys) {
@@ -2383,13 +2500,13 @@ class TokenFactory {
2383
2500
  }
2384
2501
  }
2385
2502
  if (expiredKeys.length > 0) {
2386
- const kids = expiredKeys.map(({key}) => key.kid);
2503
+ const kids = expiredKeys.map(({ key }) => key.kid);
2387
2504
  this.logger.info(`Removing expired signing keys, '${kids.join("', '")}'`);
2388
2505
  this.keyStore.removeKeys(kids).catch((error) => {
2389
2506
  this.logger.error(`Failed to remove expired keys, ${error}`);
2390
2507
  });
2391
2508
  }
2392
- return {keys: validKeys.map(({key}) => key)};
2509
+ return { keys: validKeys.map(({ key }) => key) };
2393
2510
  }
2394
2511
  async getKey() {
2395
2512
  if (this.privateKeyPromise) {
@@ -2427,7 +2544,7 @@ class TokenFactory {
2427
2544
  const migrationsDir = backendCommon.resolvePackagePath("@backstage/plugin-auth-backend", "migrations");
2428
2545
  const TABLE = "signing_keys";
2429
2546
  const parseDate = (date) => {
2430
- const parsedDate = typeof date === "string" ? luxon.DateTime.fromSQL(date, {zone: "UTC"}) : luxon.DateTime.fromJSDate(date);
2547
+ const parsedDate = typeof date === "string" ? luxon.DateTime.fromSQL(date, { zone: "UTC" }) : luxon.DateTime.fromJSDate(date);
2431
2548
  if (!parsedDate.isValid) {
2432
2549
  throw new Error(`Failed to parse date, reason: ${parsedDate.invalidReason}, explanation: ${parsedDate.invalidExplanation}`);
2433
2550
  }
@@ -2435,7 +2552,7 @@ const parseDate = (date) => {
2435
2552
  };
2436
2553
  class DatabaseKeyStore {
2437
2554
  static async create(options) {
2438
- const {database} = options;
2555
+ const { database } = options;
2439
2556
  await database.migrate.latest({
2440
2557
  directory: migrationsDir
2441
2558
  });
@@ -2466,7 +2583,7 @@ class DatabaseKeyStore {
2466
2583
 
2467
2584
  class MemoryKeyStore {
2468
2585
  constructor() {
2469
- this.keys = new Map();
2586
+ this.keys = /* @__PURE__ */ new Map();
2470
2587
  }
2471
2588
  async addKey(key) {
2472
2589
  this.keys.set(key.kid, {
@@ -2481,7 +2598,7 @@ class MemoryKeyStore {
2481
2598
  }
2482
2599
  async listKeys() {
2483
2600
  return {
2484
- items: Array.from(this.keys).map(([, {createdAt, key: keyStr}]) => ({
2601
+ items: Array.from(this.keys).map(([, { createdAt, key: keyStr }]) => ({
2485
2602
  createdAt,
2486
2603
  key: JSON.parse(keyStr)
2487
2604
  }))
@@ -2498,7 +2615,7 @@ class FirestoreKeyStore {
2498
2615
  this.timeout = timeout;
2499
2616
  }
2500
2617
  static async create(settings) {
2501
- const {path, timeout, ...firestoreSettings} = settings != null ? settings : {};
2618
+ const { path, timeout, ...firestoreSettings } = settings != null ? settings : {};
2502
2619
  const database = new firestore.Firestore(firestoreSettings);
2503
2620
  return new FirestoreKeyStore(database, path != null ? path : DEFAULT_DOCUMENT_PATH, timeout != null ? timeout : DEFAULT_TIMEOUT_MS);
2504
2621
  }
@@ -2546,7 +2663,7 @@ class FirestoreKeyStore {
2546
2663
  class KeyStores {
2547
2664
  static async fromConfig(config, options) {
2548
2665
  var _a;
2549
- const {logger, database} = options != null ? options : {};
2666
+ const { logger, database } = options != null ? options : {};
2550
2667
  const ks = config.getOptionalConfig("auth.keyStore");
2551
2668
  const provider = (_a = ks == null ? void 0 : ks.getOptionalString("provider")) != null ? _a : "database";
2552
2669
  logger == null ? void 0 : logger.info(`Configuring "${provider}" as KeyStore provider`);
@@ -2579,36 +2696,31 @@ class KeyStores {
2579
2696
  }
2580
2697
  }
2581
2698
 
2582
- async function createRouter({
2583
- logger,
2584
- config,
2585
- discovery,
2586
- database,
2587
- providerFactories
2588
- }) {
2589
- const router = Router__default['default']();
2699
+ async function createRouter(options) {
2700
+ const { logger, config, discovery, database, providerFactories } = options;
2701
+ const router = Router__default["default"]();
2590
2702
  const appUrl = config.getString("app.baseUrl");
2591
2703
  const authUrl = await discovery.getExternalBaseUrl("auth");
2592
- const keyStore = await KeyStores.fromConfig(config, {logger, database});
2704
+ const keyStore = await KeyStores.fromConfig(config, { logger, database });
2593
2705
  const keyDurationSeconds = 3600;
2594
2706
  const tokenIssuer = new TokenFactory({
2595
2707
  issuer: authUrl,
2596
2708
  keyStore,
2597
2709
  keyDurationSeconds,
2598
- logger: logger.child({component: "token-factory"})
2710
+ logger: logger.child({ component: "token-factory" })
2599
2711
  });
2600
- const catalogApi = new catalogClient.CatalogClient({discoveryApi: discovery});
2712
+ const catalogApi = new catalogClient.CatalogClient({ discoveryApi: discovery });
2601
2713
  const secret = config.getOptionalString("auth.session.secret");
2602
2714
  if (secret) {
2603
- router.use(cookieParser__default['default'](secret));
2604
- router.use(session__default['default']({secret, saveUninitialized: false, resave: false}));
2605
- router.use(passport__default['default'].initialize());
2606
- router.use(passport__default['default'].session());
2715
+ router.use(cookieParser__default["default"](secret));
2716
+ router.use(session__default["default"]({ secret, saveUninitialized: false, resave: false }));
2717
+ router.use(passport__default["default"].initialize());
2718
+ router.use(passport__default["default"].session());
2607
2719
  } else {
2608
- router.use(cookieParser__default['default']());
2720
+ router.use(cookieParser__default["default"]());
2609
2721
  }
2610
- router.use(express__default['default'].urlencoded({extended: false}));
2611
- router.use(express__default['default'].json());
2722
+ router.use(express__default["default"].urlencoded({ extended: false }));
2723
+ router.use(express__default["default"].json());
2612
2724
  const allProviderFactories = {
2613
2725
  ...factories,
2614
2726
  ...providerFactories
@@ -2622,14 +2734,14 @@ async function createRouter({
2622
2734
  try {
2623
2735
  const provider = providerFactory({
2624
2736
  providerId,
2625
- globalConfig: {baseUrl: authUrl, appUrl, isOriginAllowed},
2737
+ globalConfig: { baseUrl: authUrl, appUrl, isOriginAllowed },
2626
2738
  config: providersConfig.getConfig(providerId),
2627
2739
  logger,
2628
2740
  tokenIssuer,
2629
2741
  discovery,
2630
2742
  catalogApi
2631
2743
  });
2632
- const r = Router__default['default']();
2744
+ const r = Router__default["default"]();
2633
2745
  r.get("/start", provider.start.bind(provider));
2634
2746
  r.get("/handler/frame", provider.frameHandler.bind(provider));
2635
2747
  r.post("/handler/frame", provider.frameHandler.bind(provider));
@@ -2661,7 +2773,7 @@ async function createRouter({
2661
2773
  baseUrl: authUrl
2662
2774
  }));
2663
2775
  router.use("/:provider/", (req) => {
2664
- const {provider} = req.params;
2776
+ const { provider } = req.params;
2665
2777
  throw new errors.NotFoundError(`Unknown auth provider '${provider}'`);
2666
2778
  });
2667
2779
  return router;
@@ -2669,9 +2781,9 @@ async function createRouter({
2669
2781
  function createOriginFilter(config) {
2670
2782
  var _a;
2671
2783
  const appUrl = config.getString("app.baseUrl");
2672
- const {origin: appOrigin} = new URL(appUrl);
2784
+ const { origin: appOrigin } = new URL(appUrl);
2673
2785
  const allowedOrigins = config.getOptionalStringArray("auth.experimentalExtraAllowedOrigins");
2674
- const allowedOriginPatterns = (_a = allowedOrigins == null ? void 0 : allowedOrigins.map((pattern) => new minimatch.Minimatch(pattern, {nocase: true, noglobstar: true}))) != null ? _a : [];
2786
+ const allowedOriginPatterns = (_a = allowedOrigins == null ? void 0 : allowedOrigins.map((pattern) => new minimatch.Minimatch(pattern, { nocase: true, noglobstar: true }))) != null ? _a : [];
2675
2787
  return (origin) => {
2676
2788
  if (origin === appOrigin) {
2677
2789
  return true;
@@ -2680,6 +2792,7 @@ function createOriginFilter(config) {
2680
2792
  };
2681
2793
  }
2682
2794
 
2795
+ exports.CatalogIdentityClient = CatalogIdentityClient;
2683
2796
  exports.IdentityClient = IdentityClient;
2684
2797
  exports.OAuthAdapter = OAuthAdapter;
2685
2798
  exports.OAuthEnvironmentHandler = OAuthEnvironmentHandler;
@@ -2693,16 +2806,20 @@ exports.createGitlabProvider = createGitlabProvider;
2693
2806
  exports.createGoogleProvider = createGoogleProvider;
2694
2807
  exports.createMicrosoftProvider = createMicrosoftProvider;
2695
2808
  exports.createOAuth2Provider = createOAuth2Provider;
2809
+ exports.createOidcProvider = createOidcProvider;
2696
2810
  exports.createOktaProvider = createOktaProvider;
2697
2811
  exports.createOriginFilter = createOriginFilter;
2698
2812
  exports.createRouter = createRouter;
2813
+ exports.createSamlProvider = createSamlProvider;
2699
2814
  exports.defaultAuthProviderFactories = factories;
2700
2815
  exports.encodeState = encodeState;
2701
2816
  exports.ensuresXRequestedWith = ensuresXRequestedWith;
2817
+ exports.getEntityClaims = getEntityClaims;
2702
2818
  exports.googleEmailSignInResolver = googleEmailSignInResolver;
2703
2819
  exports.microsoftEmailSignInResolver = microsoftEmailSignInResolver;
2704
2820
  exports.oktaEmailSignInResolver = oktaEmailSignInResolver;
2705
2821
  exports.postMessageResponse = postMessageResponse;
2822
+ exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
2706
2823
  exports.readState = readState;
2707
2824
  exports.verifyNonce = verifyNonce;
2708
2825
  //# sourceMappingURL=index.cjs.js.map