@backstage/plugin-auth-backend 0.13.0-next.1 → 0.13.0-next.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/CHANGELOG.md +132 -0
- package/config.d.ts +3 -0
- package/dist/index.cjs.js +794 -1121
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +632 -63
- package/package.json +5 -5
package/dist/index.cjs.js
CHANGED
|
@@ -11,7 +11,6 @@ var pickBy = require('lodash/pickBy');
|
|
|
11
11
|
var crypto = require('crypto');
|
|
12
12
|
var url = require('url');
|
|
13
13
|
var jwtDecoder = require('jwt-decode');
|
|
14
|
-
var catalogModel = require('@backstage/catalog-model');
|
|
15
14
|
var fetch = require('node-fetch');
|
|
16
15
|
var NodeCache = require('node-cache');
|
|
17
16
|
var jose = require('jose');
|
|
@@ -29,6 +28,7 @@ var googleAuthLibrary = require('google-auth-library');
|
|
|
29
28
|
var catalogClient = require('@backstage/catalog-client');
|
|
30
29
|
var uuid = require('uuid');
|
|
31
30
|
var luxon = require('luxon');
|
|
31
|
+
var catalogModel = require('@backstage/catalog-model');
|
|
32
32
|
var backendCommon = require('@backstage/backend-common');
|
|
33
33
|
var firestore = require('@google-cloud/firestore');
|
|
34
34
|
var lodash = require('lodash');
|
|
@@ -542,75 +542,12 @@ const executeFetchUserProfileStrategy = async (providerStrategy, accessToken) =>
|
|
|
542
542
|
});
|
|
543
543
|
};
|
|
544
544
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
const filter = {
|
|
552
|
-
kind: "user"
|
|
553
|
-
};
|
|
554
|
-
for (const [key, value] of Object.entries(query.annotations)) {
|
|
555
|
-
filter[`metadata.annotations.${key}`] = value;
|
|
556
|
-
}
|
|
557
|
-
const { token } = await this.tokenManager.getToken();
|
|
558
|
-
const { items } = await this.catalogApi.getEntities({ filter }, { token });
|
|
559
|
-
if (items.length !== 1) {
|
|
560
|
-
if (items.length > 1) {
|
|
561
|
-
throw new errors.ConflictError("User lookup resulted in multiple matches");
|
|
562
|
-
} else {
|
|
563
|
-
throw new errors.NotFoundError("User not found");
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
return items[0];
|
|
567
|
-
}
|
|
568
|
-
async resolveCatalogMembership(query) {
|
|
569
|
-
const { entityRefs, logger } = query;
|
|
570
|
-
const resolvedEntityRefs = entityRefs.map((ref) => {
|
|
571
|
-
try {
|
|
572
|
-
const parsedRef = catalogModel.parseEntityRef(ref.toLocaleLowerCase("en-US"), {
|
|
573
|
-
defaultKind: "user",
|
|
574
|
-
defaultNamespace: "default"
|
|
575
|
-
});
|
|
576
|
-
return parsedRef;
|
|
577
|
-
} catch {
|
|
578
|
-
logger == null ? void 0 : logger.warn(`Failed to parse entityRef from ${ref}, ignoring`);
|
|
579
|
-
return null;
|
|
580
|
-
}
|
|
581
|
-
}).filter((ref) => ref !== null);
|
|
582
|
-
const filter = resolvedEntityRefs.map((ref) => ({
|
|
583
|
-
kind: ref.kind,
|
|
584
|
-
"metadata.namespace": ref.namespace,
|
|
585
|
-
"metadata.name": ref.name
|
|
586
|
-
}));
|
|
587
|
-
const { token } = await this.tokenManager.getToken();
|
|
588
|
-
const entities = await this.catalogApi.getEntities({ filter }, { token }).then((r) => r.items);
|
|
589
|
-
if (entityRefs.length !== entities.length) {
|
|
590
|
-
const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
|
|
591
|
-
const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
|
|
592
|
-
logger == null ? void 0 : logger.debug(`Entities not found for refs ${missingEntityNames.join()}`);
|
|
593
|
-
}
|
|
594
|
-
const memberOf = entities.flatMap((e) => {
|
|
595
|
-
var _a, _b;
|
|
596
|
-
return (_b = (_a = e.relations) == null ? void 0 : _a.filter((r) => r.type === catalogModel.RELATION_MEMBER_OF).map((r) => r.targetRef)) != null ? _b : [];
|
|
597
|
-
});
|
|
598
|
-
const newEntityRefs = [
|
|
599
|
-
...new Set(resolvedEntityRefs.map(catalogModel.stringifyEntityRef).concat(memberOf))
|
|
600
|
-
];
|
|
601
|
-
logger == null ? void 0 : logger.debug(`Found catalog membership: ${newEntityRefs.join()}`);
|
|
602
|
-
return newEntityRefs;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
function getEntityClaims(entity) {
|
|
607
|
-
var _a, _b;
|
|
608
|
-
const userRef = catalogModel.stringifyEntityRef(entity);
|
|
609
|
-
const membershipRefs = (_b = (_a = entity.relations) == null ? void 0 : _a.filter((r) => r.type === catalogModel.RELATION_MEMBER_OF && r.targetRef.startsWith("group:")).map((r) => r.targetRef)) != null ? _b : [];
|
|
610
|
-
return {
|
|
611
|
-
sub: userRef,
|
|
612
|
-
ent: [userRef, ...membershipRefs]
|
|
613
|
-
};
|
|
545
|
+
function createAuthProviderIntegration(config) {
|
|
546
|
+
var _a;
|
|
547
|
+
return Object.freeze({
|
|
548
|
+
...config,
|
|
549
|
+
resolvers: Object.freeze((_a = config.resolvers) != null ? _a : {})
|
|
550
|
+
});
|
|
614
551
|
}
|
|
615
552
|
|
|
616
553
|
const atlassianDefaultAuthHandler = async ({
|
|
@@ -621,9 +558,7 @@ const atlassianDefaultAuthHandler = async ({
|
|
|
621
558
|
});
|
|
622
559
|
class AtlassianAuthProvider {
|
|
623
560
|
constructor(options) {
|
|
624
|
-
this.
|
|
625
|
-
this.logger = options.logger;
|
|
626
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
561
|
+
this.resolverContext = options.resolverContext;
|
|
627
562
|
this.authHandler = options.authHandler;
|
|
628
563
|
this.signInResolver = options.signInResolver;
|
|
629
564
|
this._strategy = new AtlassianStrategy({
|
|
@@ -653,12 +588,7 @@ class AtlassianAuthProvider {
|
|
|
653
588
|
};
|
|
654
589
|
}
|
|
655
590
|
async handleResult(result) {
|
|
656
|
-
const
|
|
657
|
-
logger: this.logger,
|
|
658
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
659
|
-
tokenIssuer: this.tokenIssuer
|
|
660
|
-
};
|
|
661
|
-
const { profile } = await this.authHandler(result, context);
|
|
591
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
662
592
|
const response = {
|
|
663
593
|
providerInfo: {
|
|
664
594
|
idToken: result.params.id_token,
|
|
@@ -672,7 +602,7 @@ class AtlassianAuthProvider {
|
|
|
672
602
|
response.backstageIdentity = await this.signInResolver({
|
|
673
603
|
result,
|
|
674
604
|
profile
|
|
675
|
-
},
|
|
605
|
+
}, this.resolverContext);
|
|
676
606
|
}
|
|
677
607
|
return response;
|
|
678
608
|
}
|
|
@@ -689,45 +619,33 @@ class AtlassianAuthProvider {
|
|
|
689
619
|
};
|
|
690
620
|
}
|
|
691
621
|
}
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
providerId,
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
clientSecret,
|
|
716
|
-
scopes,
|
|
717
|
-
callbackUrl,
|
|
718
|
-
authHandler,
|
|
719
|
-
signInResolver: (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver,
|
|
720
|
-
catalogIdentityClient,
|
|
721
|
-
logger,
|
|
722
|
-
tokenIssuer
|
|
723
|
-
});
|
|
724
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
725
|
-
providerId,
|
|
726
|
-
tokenIssuer,
|
|
727
|
-
callbackUrl
|
|
622
|
+
const atlassian = createAuthProviderIntegration({
|
|
623
|
+
create(options) {
|
|
624
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
625
|
+
var _a, _b;
|
|
626
|
+
const clientId = envConfig.getString("clientId");
|
|
627
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
628
|
+
const scopes = envConfig.getString("scopes");
|
|
629
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
630
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
631
|
+
const authHandler = (_a = options == null ? void 0 : options.authHandler) != null ? _a : atlassianDefaultAuthHandler;
|
|
632
|
+
const provider = new AtlassianAuthProvider({
|
|
633
|
+
clientId,
|
|
634
|
+
clientSecret,
|
|
635
|
+
scopes,
|
|
636
|
+
callbackUrl,
|
|
637
|
+
authHandler,
|
|
638
|
+
signInResolver: (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver,
|
|
639
|
+
resolverContext
|
|
640
|
+
});
|
|
641
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
642
|
+
providerId,
|
|
643
|
+
callbackUrl
|
|
644
|
+
});
|
|
728
645
|
});
|
|
729
|
-
}
|
|
730
|
-
};
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
const createAtlassianProvider = atlassian.create;
|
|
731
649
|
|
|
732
650
|
class Auth0Strategy extends OAuth2Strategy__default["default"] {
|
|
733
651
|
constructor(options, verify) {
|
|
@@ -746,9 +664,7 @@ class Auth0AuthProvider {
|
|
|
746
664
|
constructor(options) {
|
|
747
665
|
this.signInResolver = options.signInResolver;
|
|
748
666
|
this.authHandler = options.authHandler;
|
|
749
|
-
this.
|
|
750
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
751
|
-
this.logger = options.logger;
|
|
667
|
+
this.resolverContext = options.resolverContext;
|
|
752
668
|
this._strategy = new Auth0Strategy({
|
|
753
669
|
clientID: options.clientId,
|
|
754
670
|
clientSecret: options.clientSecret,
|
|
@@ -794,12 +710,7 @@ class Auth0AuthProvider {
|
|
|
794
710
|
};
|
|
795
711
|
}
|
|
796
712
|
async handleResult(result) {
|
|
797
|
-
const
|
|
798
|
-
logger: this.logger,
|
|
799
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
800
|
-
tokenIssuer: this.tokenIssuer
|
|
801
|
-
};
|
|
802
|
-
const { profile } = await this.authHandler(result, context);
|
|
713
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
803
714
|
const response = {
|
|
804
715
|
providerInfo: {
|
|
805
716
|
idToken: result.params.id_token,
|
|
@@ -813,62 +724,42 @@ class Auth0AuthProvider {
|
|
|
813
724
|
response.backstageIdentity = await this.signInResolver({
|
|
814
725
|
result,
|
|
815
726
|
profile
|
|
816
|
-
},
|
|
727
|
+
}, this.resolverContext);
|
|
817
728
|
}
|
|
818
729
|
return response;
|
|
819
730
|
}
|
|
820
731
|
}
|
|
821
|
-
const
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
});
|
|
849
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
850
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
851
|
-
});
|
|
852
|
-
const signInResolver = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : defaultSignInResolver$1;
|
|
853
|
-
const provider = new Auth0AuthProvider({
|
|
854
|
-
clientId,
|
|
855
|
-
clientSecret,
|
|
856
|
-
callbackUrl,
|
|
857
|
-
domain,
|
|
858
|
-
authHandler,
|
|
859
|
-
signInResolver,
|
|
860
|
-
tokenIssuer,
|
|
861
|
-
catalogIdentityClient,
|
|
862
|
-
logger
|
|
863
|
-
});
|
|
864
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
865
|
-
disableRefresh: true,
|
|
866
|
-
providerId,
|
|
867
|
-
tokenIssuer,
|
|
868
|
-
callbackUrl
|
|
732
|
+
const auth0 = createAuthProviderIntegration({
|
|
733
|
+
create(options) {
|
|
734
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
735
|
+
var _a;
|
|
736
|
+
const clientId = envConfig.getString("clientId");
|
|
737
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
738
|
+
const domain = envConfig.getString("domain");
|
|
739
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
740
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
741
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
742
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
743
|
+
});
|
|
744
|
+
const signInResolver = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver;
|
|
745
|
+
const provider = new Auth0AuthProvider({
|
|
746
|
+
clientId,
|
|
747
|
+
clientSecret,
|
|
748
|
+
callbackUrl,
|
|
749
|
+
domain,
|
|
750
|
+
authHandler,
|
|
751
|
+
signInResolver,
|
|
752
|
+
resolverContext
|
|
753
|
+
});
|
|
754
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
755
|
+
disableRefresh: true,
|
|
756
|
+
providerId,
|
|
757
|
+
callbackUrl
|
|
758
|
+
});
|
|
869
759
|
});
|
|
870
|
-
}
|
|
871
|
-
};
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
const createAuth0Provider = auth0.create;
|
|
872
763
|
|
|
873
764
|
const ALB_JWT_HEADER = "x-amzn-oidc-data";
|
|
874
765
|
const ALB_ACCESS_TOKEN_HEADER = "x-amzn-oidc-accesstoken";
|
|
@@ -882,9 +773,7 @@ class AwsAlbAuthProvider {
|
|
|
882
773
|
this.issuer = options.issuer;
|
|
883
774
|
this.authHandler = options.authHandler;
|
|
884
775
|
this.signInResolver = options.signInResolver;
|
|
885
|
-
this.
|
|
886
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
887
|
-
this.logger = options.logger;
|
|
776
|
+
this.resolverContext = options.resolverContext;
|
|
888
777
|
this.keyCache = new NodeCache__default["default"]({ stdTTL: 3600 });
|
|
889
778
|
}
|
|
890
779
|
frameHandler() {
|
|
@@ -896,9 +785,7 @@ class AwsAlbAuthProvider {
|
|
|
896
785
|
const response = await this.handleResult(result);
|
|
897
786
|
res.json(response);
|
|
898
787
|
} catch (e) {
|
|
899
|
-
|
|
900
|
-
res.status(401);
|
|
901
|
-
res.end();
|
|
788
|
+
throw new errors.AuthenticationError("Exception occurred during AWS ALB token refresh", e);
|
|
902
789
|
}
|
|
903
790
|
}
|
|
904
791
|
start() {
|
|
@@ -942,16 +829,11 @@ class AwsAlbAuthProvider {
|
|
|
942
829
|
}
|
|
943
830
|
}
|
|
944
831
|
async handleResult(result) {
|
|
945
|
-
const
|
|
946
|
-
tokenIssuer: this.tokenIssuer,
|
|
947
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
948
|
-
logger: this.logger
|
|
949
|
-
};
|
|
950
|
-
const { profile } = await this.authHandler(result, context);
|
|
832
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
951
833
|
const backstageIdentity = await this.signInResolver({
|
|
952
834
|
result,
|
|
953
835
|
profile
|
|
954
|
-
},
|
|
836
|
+
}, this.resolverContext);
|
|
955
837
|
return {
|
|
956
838
|
providerInfo: {
|
|
957
839
|
accessToken: result.accessToken,
|
|
@@ -966,46 +848,40 @@ class AwsAlbAuthProvider {
|
|
|
966
848
|
if (optionalCacheKey) {
|
|
967
849
|
return crypto__namespace.createPublicKey(optionalCacheKey);
|
|
968
850
|
}
|
|
969
|
-
const keyText = await fetch__default["default"](`https://public-keys.auth.elb.${this.region}.amazonaws.com/${keyId}`).then((response) => response.text());
|
|
851
|
+
const keyText = await fetch__default["default"](`https://public-keys.auth.elb.${encodeURIComponent(this.region)}.amazonaws.com/${encodeURIComponent(keyId)}`).then((response) => response.text());
|
|
970
852
|
const keyValue = crypto__namespace.createPublicKey(keyText);
|
|
971
853
|
this.keyCache.set(keyId, keyValue.export({ format: "pem", type: "spki" }));
|
|
972
854
|
return keyValue;
|
|
973
855
|
}
|
|
974
856
|
}
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
logger
|
|
998
|
-
});
|
|
999
|
-
};
|
|
1000
|
-
};
|
|
857
|
+
const awsAlb = createAuthProviderIntegration({
|
|
858
|
+
create(options) {
|
|
859
|
+
return ({ config, resolverContext }) => {
|
|
860
|
+
const region = config.getString("region");
|
|
861
|
+
const issuer = config.getOptionalString("iss");
|
|
862
|
+
if ((options == null ? void 0 : options.signIn.resolver) === void 0) {
|
|
863
|
+
throw new Error("SignInResolver is required to use this authentication provider");
|
|
864
|
+
}
|
|
865
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
866
|
+
profile: makeProfileInfo(fullProfile)
|
|
867
|
+
});
|
|
868
|
+
return new AwsAlbAuthProvider({
|
|
869
|
+
region,
|
|
870
|
+
issuer,
|
|
871
|
+
signInResolver: options == null ? void 0 : options.signIn.resolver,
|
|
872
|
+
authHandler,
|
|
873
|
+
resolverContext
|
|
874
|
+
});
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
const createAwsAlbProvider = awsAlb.create;
|
|
1001
879
|
|
|
1002
880
|
class BitbucketAuthProvider {
|
|
1003
881
|
constructor(options) {
|
|
1004
882
|
this.signInResolver = options.signInResolver;
|
|
1005
883
|
this.authHandler = options.authHandler;
|
|
1006
|
-
this.
|
|
1007
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1008
|
-
this.logger = options.logger;
|
|
884
|
+
this.resolverContext = options.resolverContext;
|
|
1009
885
|
this._strategy = new passportBitbucketOauth2.Strategy({
|
|
1010
886
|
clientID: options.clientId,
|
|
1011
887
|
clientSecret: options.clientSecret,
|
|
@@ -1051,12 +927,7 @@ class BitbucketAuthProvider {
|
|
|
1051
927
|
}
|
|
1052
928
|
async handleResult(result) {
|
|
1053
929
|
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
1054
|
-
const
|
|
1055
|
-
logger: this.logger,
|
|
1056
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1057
|
-
tokenIssuer: this.tokenIssuer
|
|
1058
|
-
};
|
|
1059
|
-
const { profile } = await this.authHandler(result, context);
|
|
930
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1060
931
|
const response = {
|
|
1061
932
|
providerInfo: {
|
|
1062
933
|
idToken: result.params.id_token,
|
|
@@ -1070,79 +941,69 @@ class BitbucketAuthProvider {
|
|
|
1070
941
|
response.backstageIdentity = await this.signInResolver({
|
|
1071
942
|
result,
|
|
1072
943
|
profile
|
|
1073
|
-
},
|
|
944
|
+
}, this.resolverContext);
|
|
1074
945
|
}
|
|
1075
946
|
return response;
|
|
1076
947
|
}
|
|
1077
948
|
}
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
949
|
+
const bitbucket = createAuthProviderIntegration({
|
|
950
|
+
create(options) {
|
|
951
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
952
|
+
var _a;
|
|
953
|
+
const clientId = envConfig.getString("clientId");
|
|
954
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
955
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
956
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
957
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
958
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
959
|
+
});
|
|
960
|
+
const provider = new BitbucketAuthProvider({
|
|
961
|
+
clientId,
|
|
962
|
+
clientSecret,
|
|
963
|
+
callbackUrl,
|
|
964
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
965
|
+
authHandler,
|
|
966
|
+
resolverContext
|
|
967
|
+
});
|
|
968
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
969
|
+
disableRefresh: false,
|
|
970
|
+
providerId,
|
|
971
|
+
callbackUrl
|
|
972
|
+
});
|
|
973
|
+
});
|
|
974
|
+
},
|
|
975
|
+
resolvers: {
|
|
976
|
+
usernameMatchingUserEntityAnnotation() {
|
|
977
|
+
return async (info, ctx) => {
|
|
978
|
+
const { result } = info;
|
|
979
|
+
if (!result.fullProfile.username) {
|
|
980
|
+
throw new Error("Bitbucket profile contained no Username");
|
|
981
|
+
}
|
|
982
|
+
return ctx.signInWithCatalogUser({
|
|
983
|
+
annotations: {
|
|
984
|
+
"bitbucket.org/username": result.fullProfile.username
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
};
|
|
988
|
+
},
|
|
989
|
+
userIdMatchingUserEntityAnnotation() {
|
|
990
|
+
return async (info, ctx) => {
|
|
991
|
+
const { result } = info;
|
|
992
|
+
if (!result.fullProfile.id) {
|
|
993
|
+
throw new Error("Bitbucket profile contained no User ID");
|
|
994
|
+
}
|
|
995
|
+
return ctx.signInWithCatalogUser({
|
|
996
|
+
annotations: {
|
|
997
|
+
"bitbucket.org/user-id": result.fullProfile.id
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
};
|
|
1086
1001
|
}
|
|
1087
|
-
});
|
|
1088
|
-
const claims = getEntityClaims(entity);
|
|
1089
|
-
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1090
|
-
return { id: entity.metadata.name, entity, token };
|
|
1091
|
-
};
|
|
1092
|
-
const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
1093
|
-
const { result } = info;
|
|
1094
|
-
if (!result.fullProfile.id) {
|
|
1095
|
-
throw new Error("Bitbucket profile contained no User ID");
|
|
1096
1002
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
});
|
|
1102
|
-
const claims = getEntityClaims(entity);
|
|
1103
|
-
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1104
|
-
return { id: entity.metadata.name, entity, token };
|
|
1105
|
-
};
|
|
1106
|
-
const createBitbucketProvider = (options) => {
|
|
1107
|
-
return ({
|
|
1108
|
-
providerId,
|
|
1109
|
-
globalConfig,
|
|
1110
|
-
config,
|
|
1111
|
-
tokenIssuer,
|
|
1112
|
-
tokenManager,
|
|
1113
|
-
catalogApi,
|
|
1114
|
-
logger
|
|
1115
|
-
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1116
|
-
var _a;
|
|
1117
|
-
const clientId = envConfig.getString("clientId");
|
|
1118
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
1119
|
-
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1120
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1121
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1122
|
-
catalogApi,
|
|
1123
|
-
tokenManager
|
|
1124
|
-
});
|
|
1125
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1126
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1127
|
-
});
|
|
1128
|
-
const provider = new BitbucketAuthProvider({
|
|
1129
|
-
clientId,
|
|
1130
|
-
clientSecret,
|
|
1131
|
-
callbackUrl,
|
|
1132
|
-
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
1133
|
-
authHandler,
|
|
1134
|
-
tokenIssuer,
|
|
1135
|
-
catalogIdentityClient,
|
|
1136
|
-
logger
|
|
1137
|
-
});
|
|
1138
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1139
|
-
disableRefresh: false,
|
|
1140
|
-
providerId,
|
|
1141
|
-
tokenIssuer,
|
|
1142
|
-
callbackUrl
|
|
1143
|
-
});
|
|
1144
|
-
});
|
|
1145
|
-
};
|
|
1003
|
+
});
|
|
1004
|
+
const createBitbucketProvider = bitbucket.create;
|
|
1005
|
+
const bitbucketUsernameSignInResolver = bitbucket.resolvers.usernameMatchingUserEntityAnnotation();
|
|
1006
|
+
const bitbucketUserIdSignInResolver = bitbucket.resolvers.userIdMatchingUserEntityAnnotation();
|
|
1146
1007
|
|
|
1147
1008
|
const ACCESS_TOKEN_PREFIX = "access-token.";
|
|
1148
1009
|
const BACKSTAGE_SESSION_EXPIRATION = 3600;
|
|
@@ -1151,9 +1012,7 @@ class GithubAuthProvider {
|
|
|
1151
1012
|
this.signInResolver = options.signInResolver;
|
|
1152
1013
|
this.authHandler = options.authHandler;
|
|
1153
1014
|
this.stateEncoder = options.stateEncoder;
|
|
1154
|
-
this.
|
|
1155
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1156
|
-
this.logger = options.logger;
|
|
1015
|
+
this.resolverContext = options.resolverContext;
|
|
1157
1016
|
this._strategy = new passportGithub2.Strategy({
|
|
1158
1017
|
clientID: options.clientId,
|
|
1159
1018
|
clientSecret: options.clientSecret,
|
|
@@ -1213,12 +1072,7 @@ class GithubAuthProvider {
|
|
|
1213
1072
|
};
|
|
1214
1073
|
}
|
|
1215
1074
|
async handleResult(result) {
|
|
1216
|
-
const
|
|
1217
|
-
logger: this.logger,
|
|
1218
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1219
|
-
tokenIssuer: this.tokenIssuer
|
|
1220
|
-
};
|
|
1221
|
-
const { profile } = await this.authHandler(result, context);
|
|
1075
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1222
1076
|
const expiresInStr = result.params.expires_in;
|
|
1223
1077
|
let expiresInSeconds = expiresInStr === void 0 ? void 0 : Number(expiresInStr);
|
|
1224
1078
|
let backstageIdentity = void 0;
|
|
@@ -1226,7 +1080,7 @@ class GithubAuthProvider {
|
|
|
1226
1080
|
backstageIdentity = await this.signInResolver({
|
|
1227
1081
|
result,
|
|
1228
1082
|
profile
|
|
1229
|
-
},
|
|
1083
|
+
}, this.resolverContext);
|
|
1230
1084
|
if (expiresInSeconds) {
|
|
1231
1085
|
expiresInSeconds = Math.min(expiresInSeconds, BACKSTAGE_SESSION_EXPIRATION);
|
|
1232
1086
|
} else {
|
|
@@ -1244,99 +1098,58 @@ class GithubAuthProvider {
|
|
|
1244
1098
|
};
|
|
1245
1099
|
}
|
|
1246
1100
|
}
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1283
|
-
catalogApi,
|
|
1284
|
-
tokenManager
|
|
1285
|
-
});
|
|
1286
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
1287
|
-
profile: makeProfileInfo(fullProfile)
|
|
1288
|
-
});
|
|
1289
|
-
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : githubDefaultSignInResolver;
|
|
1290
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1291
|
-
catalogIdentityClient,
|
|
1292
|
-
tokenIssuer,
|
|
1293
|
-
logger
|
|
1294
|
-
});
|
|
1295
|
-
const stateEncoder = (_d = options == null ? void 0 : options.stateEncoder) != null ? _d : async (req) => {
|
|
1296
|
-
return { encodedState: encodeState(req.state) };
|
|
1297
|
-
};
|
|
1298
|
-
const provider = new GithubAuthProvider({
|
|
1299
|
-
clientId,
|
|
1300
|
-
clientSecret,
|
|
1301
|
-
callbackUrl,
|
|
1302
|
-
tokenUrl,
|
|
1303
|
-
userProfileUrl,
|
|
1304
|
-
authorizationUrl,
|
|
1305
|
-
signInResolver,
|
|
1306
|
-
authHandler,
|
|
1307
|
-
tokenIssuer,
|
|
1308
|
-
catalogIdentityClient,
|
|
1309
|
-
stateEncoder,
|
|
1310
|
-
logger
|
|
1311
|
-
});
|
|
1312
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1313
|
-
persistScopes: true,
|
|
1314
|
-
providerId,
|
|
1315
|
-
tokenIssuer,
|
|
1316
|
-
callbackUrl
|
|
1101
|
+
const github = createAuthProviderIntegration({
|
|
1102
|
+
create(options) {
|
|
1103
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1104
|
+
var _a, _b, _c;
|
|
1105
|
+
const clientId = envConfig.getString("clientId");
|
|
1106
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1107
|
+
const enterpriseInstanceUrl = (_a = envConfig.getOptionalString("enterpriseInstanceUrl")) == null ? void 0 : _a.replace(/\/$/, "");
|
|
1108
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1109
|
+
const authorizationUrl = enterpriseInstanceUrl ? `${enterpriseInstanceUrl}/login/oauth/authorize` : void 0;
|
|
1110
|
+
const tokenUrl = enterpriseInstanceUrl ? `${enterpriseInstanceUrl}/login/oauth/access_token` : void 0;
|
|
1111
|
+
const userProfileUrl = enterpriseInstanceUrl ? `${enterpriseInstanceUrl}/api/v3/user` : void 0;
|
|
1112
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1113
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
1114
|
+
profile: makeProfileInfo(fullProfile)
|
|
1115
|
+
});
|
|
1116
|
+
const stateEncoder = (_b = options == null ? void 0 : options.stateEncoder) != null ? _b : async (req) => {
|
|
1117
|
+
return { encodedState: encodeState(req.state) };
|
|
1118
|
+
};
|
|
1119
|
+
const provider = new GithubAuthProvider({
|
|
1120
|
+
clientId,
|
|
1121
|
+
clientSecret,
|
|
1122
|
+
callbackUrl,
|
|
1123
|
+
tokenUrl,
|
|
1124
|
+
userProfileUrl,
|
|
1125
|
+
authorizationUrl,
|
|
1126
|
+
signInResolver: (_c = options == null ? void 0 : options.signIn) == null ? void 0 : _c.resolver,
|
|
1127
|
+
authHandler,
|
|
1128
|
+
stateEncoder,
|
|
1129
|
+
resolverContext
|
|
1130
|
+
});
|
|
1131
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1132
|
+
persistScopes: true,
|
|
1133
|
+
providerId,
|
|
1134
|
+
callbackUrl
|
|
1135
|
+
});
|
|
1317
1136
|
});
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
namespace: catalogModel.DEFAULT_NAMESPACE,
|
|
1330
|
-
name: id
|
|
1331
|
-
});
|
|
1332
|
-
const token = await ctx.tokenIssuer.issueToken({
|
|
1333
|
-
claims: {
|
|
1334
|
-
sub: entityRef,
|
|
1335
|
-
ent: [entityRef]
|
|
1137
|
+
},
|
|
1138
|
+
resolvers: {
|
|
1139
|
+
usernameMatchingUserEntityName: () => {
|
|
1140
|
+
return async (info, ctx) => {
|
|
1141
|
+
const { fullProfile } = info.result;
|
|
1142
|
+
const userId = fullProfile.username;
|
|
1143
|
+
if (!userId) {
|
|
1144
|
+
throw new Error(`GitHub user profile does not contain a username`);
|
|
1145
|
+
}
|
|
1146
|
+
return ctx.signInWithCatalogUser({ entityRef: { name: userId } });
|
|
1147
|
+
};
|
|
1336
1148
|
}
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
const createGithubProvider = github.create;
|
|
1152
|
+
|
|
1340
1153
|
const gitlabDefaultAuthHandler = async ({
|
|
1341
1154
|
fullProfile,
|
|
1342
1155
|
params
|
|
@@ -1345,9 +1158,7 @@ const gitlabDefaultAuthHandler = async ({
|
|
|
1345
1158
|
});
|
|
1346
1159
|
class GitlabAuthProvider {
|
|
1347
1160
|
constructor(options) {
|
|
1348
|
-
this.
|
|
1349
|
-
this.logger = options.logger;
|
|
1350
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
1161
|
+
this.resolverContext = options.resolverContext;
|
|
1351
1162
|
this.authHandler = options.authHandler;
|
|
1352
1163
|
this.signInResolver = options.signInResolver;
|
|
1353
1164
|
this._strategy = new passportGitlab2.Strategy({
|
|
@@ -1387,12 +1198,7 @@ class GitlabAuthProvider {
|
|
|
1387
1198
|
};
|
|
1388
1199
|
}
|
|
1389
1200
|
async handleResult(result) {
|
|
1390
|
-
const
|
|
1391
|
-
logger: this.logger,
|
|
1392
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1393
|
-
tokenIssuer: this.tokenIssuer
|
|
1394
|
-
};
|
|
1395
|
-
const { profile } = await this.authHandler(result, context);
|
|
1201
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1396
1202
|
const response = {
|
|
1397
1203
|
providerInfo: {
|
|
1398
1204
|
idToken: result.params.id_token,
|
|
@@ -1406,67 +1212,58 @@ class GitlabAuthProvider {
|
|
|
1406
1212
|
response.backstageIdentity = await this.signInResolver({
|
|
1407
1213
|
result,
|
|
1408
1214
|
profile
|
|
1409
|
-
},
|
|
1215
|
+
}, this.resolverContext);
|
|
1410
1216
|
}
|
|
1411
1217
|
return response;
|
|
1412
1218
|
}
|
|
1413
1219
|
}
|
|
1414
|
-
const
|
|
1415
|
-
|
|
1416
|
-
providerId,
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
tokenIssuer,
|
|
1440
|
-
logger
|
|
1441
|
-
});
|
|
1442
|
-
const provider = new GitlabAuthProvider({
|
|
1443
|
-
clientId,
|
|
1444
|
-
clientSecret,
|
|
1445
|
-
callbackUrl,
|
|
1446
|
-
baseUrl,
|
|
1447
|
-
authHandler,
|
|
1448
|
-
signInResolver,
|
|
1449
|
-
catalogIdentityClient,
|
|
1450
|
-
logger,
|
|
1451
|
-
tokenIssuer
|
|
1452
|
-
});
|
|
1453
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1454
|
-
disableRefresh: false,
|
|
1455
|
-
providerId,
|
|
1456
|
-
tokenIssuer,
|
|
1457
|
-
callbackUrl
|
|
1220
|
+
const gitlab = createAuthProviderIntegration({
|
|
1221
|
+
create(options) {
|
|
1222
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1223
|
+
var _a, _b;
|
|
1224
|
+
const clientId = envConfig.getString("clientId");
|
|
1225
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1226
|
+
const audience = envConfig.getOptionalString("audience");
|
|
1227
|
+
const baseUrl = audience || "https://gitlab.com";
|
|
1228
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1229
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1230
|
+
const authHandler = (_a = options == null ? void 0 : options.authHandler) != null ? _a : gitlabDefaultAuthHandler;
|
|
1231
|
+
const provider = new GitlabAuthProvider({
|
|
1232
|
+
clientId,
|
|
1233
|
+
clientSecret,
|
|
1234
|
+
callbackUrl,
|
|
1235
|
+
baseUrl,
|
|
1236
|
+
authHandler,
|
|
1237
|
+
signInResolver: (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver,
|
|
1238
|
+
resolverContext
|
|
1239
|
+
});
|
|
1240
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1241
|
+
disableRefresh: false,
|
|
1242
|
+
providerId,
|
|
1243
|
+
callbackUrl
|
|
1244
|
+
});
|
|
1458
1245
|
});
|
|
1246
|
+
}
|
|
1247
|
+
});
|
|
1248
|
+
const createGitlabProvider = gitlab.create;
|
|
1249
|
+
|
|
1250
|
+
const commonByEmailLocalPartResolver = async (info, ctx) => {
|
|
1251
|
+
const { profile } = info;
|
|
1252
|
+
if (!profile.email) {
|
|
1253
|
+
throw new Error("Login failed, user profile does not contain an email");
|
|
1254
|
+
}
|
|
1255
|
+
const [localPart] = profile.email.split("@");
|
|
1256
|
+
return ctx.signInWithCatalogUser({
|
|
1257
|
+
entityRef: { name: localPart }
|
|
1459
1258
|
});
|
|
1460
1259
|
};
|
|
1461
1260
|
|
|
1462
1261
|
class GoogleAuthProvider {
|
|
1463
1262
|
constructor(options) {
|
|
1464
|
-
this.signInResolver = options.signInResolver;
|
|
1465
1263
|
this.authHandler = options.authHandler;
|
|
1466
|
-
this.
|
|
1467
|
-
this.
|
|
1468
|
-
this.
|
|
1469
|
-
this._strategy = new passportGoogleOauth20.Strategy({
|
|
1264
|
+
this.signInResolver = options.signInResolver;
|
|
1265
|
+
this.resolverContext = options.resolverContext;
|
|
1266
|
+
this.strategy = new passportGoogleOauth20.Strategy({
|
|
1470
1267
|
clientID: options.clientId,
|
|
1471
1268
|
clientSecret: options.clientSecret,
|
|
1472
1269
|
callbackURL: options.callbackUrl,
|
|
@@ -1483,7 +1280,7 @@ class GoogleAuthProvider {
|
|
|
1483
1280
|
});
|
|
1484
1281
|
}
|
|
1485
1282
|
async start(req) {
|
|
1486
|
-
return await executeRedirectStrategy(req, this.
|
|
1283
|
+
return await executeRedirectStrategy(req, this.strategy, {
|
|
1487
1284
|
accessType: "offline",
|
|
1488
1285
|
prompt: "consent",
|
|
1489
1286
|
scope: req.scope,
|
|
@@ -1491,15 +1288,15 @@ class GoogleAuthProvider {
|
|
|
1491
1288
|
});
|
|
1492
1289
|
}
|
|
1493
1290
|
async handler(req) {
|
|
1494
|
-
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.
|
|
1291
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
1495
1292
|
return {
|
|
1496
1293
|
response: await this.handleResult(result),
|
|
1497
1294
|
refreshToken: privateInfo.refreshToken
|
|
1498
1295
|
};
|
|
1499
1296
|
}
|
|
1500
1297
|
async refresh(req) {
|
|
1501
|
-
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(this.
|
|
1502
|
-
const fullProfile = await executeFetchUserProfileStrategy(this.
|
|
1298
|
+
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(this.strategy, req.refreshToken, req.scope);
|
|
1299
|
+
const fullProfile = await executeFetchUserProfileStrategy(this.strategy, accessToken);
|
|
1503
1300
|
return {
|
|
1504
1301
|
response: await this.handleResult({
|
|
1505
1302
|
fullProfile,
|
|
@@ -1510,12 +1307,7 @@ class GoogleAuthProvider {
|
|
|
1510
1307
|
};
|
|
1511
1308
|
}
|
|
1512
1309
|
async handleResult(result) {
|
|
1513
|
-
const
|
|
1514
|
-
logger: this.logger,
|
|
1515
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1516
|
-
tokenIssuer: this.tokenIssuer
|
|
1517
|
-
};
|
|
1518
|
-
const { profile } = await this.authHandler(result, context);
|
|
1310
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1519
1311
|
const response = {
|
|
1520
1312
|
providerInfo: {
|
|
1521
1313
|
idToken: result.params.id_token,
|
|
@@ -1529,109 +1321,63 @@ class GoogleAuthProvider {
|
|
|
1529
1321
|
response.backstageIdentity = await this.signInResolver({
|
|
1530
1322
|
result,
|
|
1531
1323
|
profile
|
|
1532
|
-
},
|
|
1324
|
+
}, this.resolverContext);
|
|
1533
1325
|
}
|
|
1534
1326
|
return response;
|
|
1535
1327
|
}
|
|
1536
1328
|
}
|
|
1537
|
-
const
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
}
|
|
1329
|
+
const google = createAuthProviderIntegration({
|
|
1330
|
+
create(options) {
|
|
1331
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1332
|
+
var _a;
|
|
1333
|
+
const clientId = envConfig.getString("clientId");
|
|
1334
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1335
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1336
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1337
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1338
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1339
|
+
});
|
|
1340
|
+
const provider = new GoogleAuthProvider({
|
|
1341
|
+
clientId,
|
|
1342
|
+
clientSecret,
|
|
1343
|
+
callbackUrl,
|
|
1344
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
1345
|
+
authHandler,
|
|
1346
|
+
resolverContext
|
|
1347
|
+
});
|
|
1348
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1349
|
+
disableRefresh: false,
|
|
1350
|
+
providerId,
|
|
1351
|
+
callbackUrl
|
|
1352
|
+
});
|
|
1562
1353
|
});
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1354
|
+
},
|
|
1355
|
+
resolvers: {
|
|
1356
|
+
emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
|
|
1357
|
+
emailMatchingUserEntityAnnotation() {
|
|
1358
|
+
return async (info, ctx) => {
|
|
1359
|
+
const { profile } = info;
|
|
1360
|
+
if (!profile.email) {
|
|
1361
|
+
throw new Error("Google profile contained no email");
|
|
1362
|
+
}
|
|
1363
|
+
return ctx.signInWithCatalogUser({
|
|
1364
|
+
annotations: {
|
|
1365
|
+
"google.com/email": profile.email
|
|
1366
|
+
}
|
|
1367
|
+
});
|
|
1368
|
+
};
|
|
1577
1369
|
}
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
const
|
|
1582
|
-
return ({
|
|
1583
|
-
providerId,
|
|
1584
|
-
globalConfig,
|
|
1585
|
-
config,
|
|
1586
|
-
tokenIssuer,
|
|
1587
|
-
tokenManager,
|
|
1588
|
-
catalogApi,
|
|
1589
|
-
logger
|
|
1590
|
-
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1591
|
-
var _a, _b;
|
|
1592
|
-
const clientId = envConfig.getString("clientId");
|
|
1593
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
1594
|
-
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1595
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1596
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1597
|
-
catalogApi,
|
|
1598
|
-
tokenManager
|
|
1599
|
-
});
|
|
1600
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1601
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1602
|
-
});
|
|
1603
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : googleDefaultSignInResolver;
|
|
1604
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1605
|
-
catalogIdentityClient,
|
|
1606
|
-
tokenIssuer,
|
|
1607
|
-
logger
|
|
1608
|
-
});
|
|
1609
|
-
const provider = new GoogleAuthProvider({
|
|
1610
|
-
clientId,
|
|
1611
|
-
clientSecret,
|
|
1612
|
-
callbackUrl,
|
|
1613
|
-
signInResolver,
|
|
1614
|
-
authHandler,
|
|
1615
|
-
tokenIssuer,
|
|
1616
|
-
catalogIdentityClient,
|
|
1617
|
-
logger
|
|
1618
|
-
});
|
|
1619
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1620
|
-
disableRefresh: false,
|
|
1621
|
-
providerId,
|
|
1622
|
-
tokenIssuer,
|
|
1623
|
-
callbackUrl
|
|
1624
|
-
});
|
|
1625
|
-
});
|
|
1626
|
-
};
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1372
|
+
const createGoogleProvider = google.create;
|
|
1373
|
+
const googleEmailSignInResolver = google.resolvers.emailMatchingUserEntityAnnotation();
|
|
1627
1374
|
|
|
1628
1375
|
class MicrosoftAuthProvider {
|
|
1629
1376
|
constructor(options) {
|
|
1630
1377
|
this.signInResolver = options.signInResolver;
|
|
1631
1378
|
this.authHandler = options.authHandler;
|
|
1632
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
1633
1379
|
this.logger = options.logger;
|
|
1634
|
-
this.
|
|
1380
|
+
this.resolverContext = options.resolverContext;
|
|
1635
1381
|
this._strategy = new passportMicrosoft.Strategy({
|
|
1636
1382
|
clientID: options.clientId,
|
|
1637
1383
|
clientSecret: options.clientSecret,
|
|
@@ -1671,12 +1417,7 @@ class MicrosoftAuthProvider {
|
|
|
1671
1417
|
async handleResult(result) {
|
|
1672
1418
|
const photo = await this.getUserPhoto(result.accessToken);
|
|
1673
1419
|
result.fullProfile.photos = photo ? [{ value: photo }] : void 0;
|
|
1674
|
-
const
|
|
1675
|
-
logger: this.logger,
|
|
1676
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1677
|
-
tokenIssuer: this.tokenIssuer
|
|
1678
|
-
};
|
|
1679
|
-
const { profile } = await this.authHandler(result, context);
|
|
1420
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1680
1421
|
const response = {
|
|
1681
1422
|
providerInfo: {
|
|
1682
1423
|
idToken: result.params.id_token,
|
|
@@ -1690,118 +1431,81 @@ class MicrosoftAuthProvider {
|
|
|
1690
1431
|
response.backstageIdentity = await this.signInResolver({
|
|
1691
1432
|
result,
|
|
1692
1433
|
profile
|
|
1693
|
-
},
|
|
1434
|
+
}, this.resolverContext);
|
|
1694
1435
|
}
|
|
1695
1436
|
return response;
|
|
1696
1437
|
}
|
|
1697
|
-
getUserPhoto(accessToken) {
|
|
1698
|
-
|
|
1699
|
-
fetch__default["default"]("https://graph.microsoft.com/v1.0/me/photos/48x48/$value", {
|
|
1438
|
+
async getUserPhoto(accessToken) {
|
|
1439
|
+
try {
|
|
1440
|
+
const res = await fetch__default["default"]("https://graph.microsoft.com/v1.0/me/photos/48x48/$value", {
|
|
1700
1441
|
headers: {
|
|
1701
1442
|
Authorization: `Bearer ${accessToken}`
|
|
1702
1443
|
}
|
|
1703
|
-
}).then((response) => response.arrayBuffer()).then((arrayBuffer) => {
|
|
1704
|
-
const imageUrl = `data:image/jpeg;base64,${Buffer.from(arrayBuffer).toString("base64")}`;
|
|
1705
|
-
resolve(imageUrl);
|
|
1706
|
-
}).catch((error) => {
|
|
1707
|
-
this.logger.warn(`Could not retrieve user profile photo from Microsoft Graph API: ${error}`);
|
|
1708
|
-
resolve(void 0);
|
|
1709
1444
|
});
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
}
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
if (!profile.email) {
|
|
1716
|
-
throw new Error("Microsoft profile contained no email");
|
|
1717
|
-
}
|
|
1718
|
-
const entity = await ctx.catalogIdentityClient.findUser({
|
|
1719
|
-
annotations: {
|
|
1720
|
-
"microsoft.com/email": profile.email
|
|
1445
|
+
const data = await res.buffer();
|
|
1446
|
+
return `data:image/jpeg;base64,${data.toString("base64")}`;
|
|
1447
|
+
} catch (error) {
|
|
1448
|
+
this.logger.warn(`Could not retrieve user profile photo from Microsoft Graph API: ${error}`);
|
|
1449
|
+
return void 0;
|
|
1721
1450
|
}
|
|
1722
|
-
});
|
|
1723
|
-
const claims = getEntityClaims(entity);
|
|
1724
|
-
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1725
|
-
return { id: entity.metadata.name, entity, token };
|
|
1726
|
-
};
|
|
1727
|
-
const microsoftDefaultSignInResolver = async (info, ctx) => {
|
|
1728
|
-
const { profile } = info;
|
|
1729
|
-
if (!profile.email) {
|
|
1730
|
-
throw new Error("Profile contained no email");
|
|
1731
1451
|
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
|
|
1764
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1765
|
-
catalogApi,
|
|
1766
|
-
tokenManager
|
|
1767
|
-
});
|
|
1768
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1769
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1770
|
-
});
|
|
1771
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : microsoftDefaultSignInResolver;
|
|
1772
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1773
|
-
catalogIdentityClient,
|
|
1774
|
-
tokenIssuer,
|
|
1775
|
-
logger
|
|
1776
|
-
});
|
|
1777
|
-
const provider = new MicrosoftAuthProvider({
|
|
1778
|
-
clientId,
|
|
1779
|
-
clientSecret,
|
|
1780
|
-
callbackUrl,
|
|
1781
|
-
authorizationUrl,
|
|
1782
|
-
tokenUrl,
|
|
1783
|
-
authHandler,
|
|
1784
|
-
signInResolver,
|
|
1785
|
-
catalogIdentityClient,
|
|
1786
|
-
logger,
|
|
1787
|
-
tokenIssuer
|
|
1788
|
-
});
|
|
1789
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1790
|
-
disableRefresh: false,
|
|
1791
|
-
providerId,
|
|
1792
|
-
tokenIssuer,
|
|
1793
|
-
callbackUrl
|
|
1452
|
+
}
|
|
1453
|
+
const microsoft = createAuthProviderIntegration({
|
|
1454
|
+
create(options) {
|
|
1455
|
+
return ({ providerId, globalConfig, config, logger, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1456
|
+
var _a;
|
|
1457
|
+
const clientId = envConfig.getString("clientId");
|
|
1458
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1459
|
+
const tenantId = envConfig.getString("tenantId");
|
|
1460
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1461
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1462
|
+
const authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;
|
|
1463
|
+
const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
|
|
1464
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1465
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1466
|
+
});
|
|
1467
|
+
const provider = new MicrosoftAuthProvider({
|
|
1468
|
+
clientId,
|
|
1469
|
+
clientSecret,
|
|
1470
|
+
callbackUrl,
|
|
1471
|
+
authorizationUrl,
|
|
1472
|
+
tokenUrl,
|
|
1473
|
+
authHandler,
|
|
1474
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
1475
|
+
logger,
|
|
1476
|
+
resolverContext
|
|
1477
|
+
});
|
|
1478
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1479
|
+
disableRefresh: false,
|
|
1480
|
+
providerId,
|
|
1481
|
+
callbackUrl
|
|
1482
|
+
});
|
|
1794
1483
|
});
|
|
1795
|
-
}
|
|
1796
|
-
|
|
1484
|
+
},
|
|
1485
|
+
resolvers: {
|
|
1486
|
+
emailMatchingUserEntityAnnotation() {
|
|
1487
|
+
return async (info, ctx) => {
|
|
1488
|
+
const { profile } = info;
|
|
1489
|
+
if (!profile.email) {
|
|
1490
|
+
throw new Error("Microsoft profile contained no email");
|
|
1491
|
+
}
|
|
1492
|
+
return ctx.signInWithCatalogUser({
|
|
1493
|
+
annotations: {
|
|
1494
|
+
"microsoft.com/email": profile.email
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
const createMicrosoftProvider = microsoft.create;
|
|
1502
|
+
const microsoftEmailSignInResolver = microsoft.resolvers.emailMatchingUserEntityAnnotation();
|
|
1797
1503
|
|
|
1798
1504
|
class OAuth2AuthProvider {
|
|
1799
1505
|
constructor(options) {
|
|
1800
1506
|
this.signInResolver = options.signInResolver;
|
|
1801
1507
|
this.authHandler = options.authHandler;
|
|
1802
|
-
this.
|
|
1803
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1804
|
-
this.logger = options.logger;
|
|
1508
|
+
this.resolverContext = options.resolverContext;
|
|
1805
1509
|
this._strategy = new OAuth2Strategy.Strategy({
|
|
1806
1510
|
clientID: options.clientId,
|
|
1807
1511
|
clientSecret: options.clientSecret,
|
|
@@ -1853,12 +1557,7 @@ class OAuth2AuthProvider {
|
|
|
1853
1557
|
};
|
|
1854
1558
|
}
|
|
1855
1559
|
async handleResult(result) {
|
|
1856
|
-
const
|
|
1857
|
-
logger: this.logger,
|
|
1858
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1859
|
-
tokenIssuer: this.tokenIssuer
|
|
1860
|
-
};
|
|
1861
|
-
const { profile } = await this.authHandler(result, context);
|
|
1560
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1862
1561
|
const response = {
|
|
1863
1562
|
providerInfo: {
|
|
1864
1563
|
idToken: result.params.id_token,
|
|
@@ -1872,7 +1571,7 @@ class OAuth2AuthProvider {
|
|
|
1872
1571
|
response.backstageIdentity = await this.signInResolver({
|
|
1873
1572
|
result,
|
|
1874
1573
|
profile
|
|
1875
|
-
},
|
|
1574
|
+
}, this.resolverContext);
|
|
1876
1575
|
}
|
|
1877
1576
|
return response;
|
|
1878
1577
|
}
|
|
@@ -1880,87 +1579,48 @@ class OAuth2AuthProvider {
|
|
|
1880
1579
|
return Buffer.from(`${clientID}:${clientSecret}`).toString("base64");
|
|
1881
1580
|
}
|
|
1882
1581
|
}
|
|
1883
|
-
const
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1917
|
-
const authorizationUrl = envConfig.getString("authorizationUrl");
|
|
1918
|
-
const tokenUrl = envConfig.getString("tokenUrl");
|
|
1919
|
-
const scope = envConfig.getOptionalString("scope");
|
|
1920
|
-
const includeBasicAuth = envConfig.getOptionalBoolean("includeBasicAuth");
|
|
1921
|
-
const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
|
|
1922
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1923
|
-
catalogApi,
|
|
1924
|
-
tokenManager
|
|
1925
|
-
});
|
|
1926
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1927
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1928
|
-
});
|
|
1929
|
-
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver;
|
|
1930
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1931
|
-
catalogIdentityClient,
|
|
1932
|
-
tokenIssuer,
|
|
1933
|
-
logger
|
|
1934
|
-
});
|
|
1935
|
-
const provider = new OAuth2AuthProvider({
|
|
1936
|
-
clientId,
|
|
1937
|
-
clientSecret,
|
|
1938
|
-
tokenIssuer,
|
|
1939
|
-
catalogIdentityClient,
|
|
1940
|
-
callbackUrl,
|
|
1941
|
-
signInResolver,
|
|
1942
|
-
authHandler,
|
|
1943
|
-
authorizationUrl,
|
|
1944
|
-
tokenUrl,
|
|
1945
|
-
scope,
|
|
1946
|
-
logger,
|
|
1947
|
-
includeBasicAuth
|
|
1948
|
-
});
|
|
1949
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1950
|
-
disableRefresh,
|
|
1951
|
-
providerId,
|
|
1952
|
-
tokenIssuer,
|
|
1953
|
-
callbackUrl
|
|
1582
|
+
const oauth2 = createAuthProviderIntegration({
|
|
1583
|
+
create(options) {
|
|
1584
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1585
|
+
var _a, _b;
|
|
1586
|
+
const clientId = envConfig.getString("clientId");
|
|
1587
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1588
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1589
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1590
|
+
const authorizationUrl = envConfig.getString("authorizationUrl");
|
|
1591
|
+
const tokenUrl = envConfig.getString("tokenUrl");
|
|
1592
|
+
const scope = envConfig.getOptionalString("scope");
|
|
1593
|
+
const includeBasicAuth = envConfig.getOptionalBoolean("includeBasicAuth");
|
|
1594
|
+
const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
|
|
1595
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1596
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1597
|
+
});
|
|
1598
|
+
const provider = new OAuth2AuthProvider({
|
|
1599
|
+
clientId,
|
|
1600
|
+
clientSecret,
|
|
1601
|
+
callbackUrl,
|
|
1602
|
+
signInResolver: (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver,
|
|
1603
|
+
authHandler,
|
|
1604
|
+
authorizationUrl,
|
|
1605
|
+
tokenUrl,
|
|
1606
|
+
scope,
|
|
1607
|
+
includeBasicAuth,
|
|
1608
|
+
resolverContext
|
|
1609
|
+
});
|
|
1610
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1611
|
+
disableRefresh,
|
|
1612
|
+
providerId,
|
|
1613
|
+
callbackUrl
|
|
1614
|
+
});
|
|
1954
1615
|
});
|
|
1955
|
-
}
|
|
1956
|
-
};
|
|
1616
|
+
}
|
|
1617
|
+
});
|
|
1618
|
+
const createOAuth2Provider = oauth2.create;
|
|
1957
1619
|
|
|
1958
1620
|
const OAUTH2_PROXY_JWT_HEADER = "X-OAUTH2-PROXY-ID-TOKEN";
|
|
1959
1621
|
class Oauth2ProxyAuthProvider {
|
|
1960
1622
|
constructor(options) {
|
|
1961
|
-
this.
|
|
1962
|
-
this.logger = options.logger;
|
|
1963
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
1623
|
+
this.resolverContext = options.resolverContext;
|
|
1964
1624
|
this.signInResolver = options.signInResolver;
|
|
1965
1625
|
this.authHandler = options.authHandler;
|
|
1966
1626
|
}
|
|
@@ -1973,25 +1633,18 @@ class Oauth2ProxyAuthProvider {
|
|
|
1973
1633
|
const response = await this.handleResult(result);
|
|
1974
1634
|
res.json(response);
|
|
1975
1635
|
} catch (e) {
|
|
1976
|
-
|
|
1977
|
-
res.status(401);
|
|
1978
|
-
res.end();
|
|
1636
|
+
throw new errors.AuthenticationError("Refresh failed", e);
|
|
1979
1637
|
}
|
|
1980
1638
|
}
|
|
1981
1639
|
start() {
|
|
1982
1640
|
return Promise.resolve(void 0);
|
|
1983
1641
|
}
|
|
1984
1642
|
async handleResult(result) {
|
|
1985
|
-
const
|
|
1986
|
-
logger: this.logger,
|
|
1987
|
-
tokenIssuer: this.tokenIssuer,
|
|
1988
|
-
catalogIdentityClient: this.catalogIdentityClient
|
|
1989
|
-
};
|
|
1990
|
-
const { profile } = await this.authHandler(result, ctx);
|
|
1643
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1991
1644
|
const backstageSignInResult = await this.signInResolver({
|
|
1992
1645
|
result,
|
|
1993
1646
|
profile
|
|
1994
|
-
},
|
|
1647
|
+
}, this.resolverContext);
|
|
1995
1648
|
return {
|
|
1996
1649
|
providerInfo: {
|
|
1997
1650
|
accessToken: result.accessToken
|
|
@@ -2013,21 +1666,20 @@ class Oauth2ProxyAuthProvider {
|
|
|
2013
1666
|
};
|
|
2014
1667
|
}
|
|
2015
1668
|
}
|
|
2016
|
-
const
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
};
|
|
1669
|
+
const oauth2Proxy = createAuthProviderIntegration({
|
|
1670
|
+
create(options) {
|
|
1671
|
+
return ({ resolverContext }) => {
|
|
1672
|
+
const signInResolver = options.signIn.resolver;
|
|
1673
|
+
const authHandler = options.authHandler;
|
|
1674
|
+
return new Oauth2ProxyAuthProvider({
|
|
1675
|
+
resolverContext,
|
|
1676
|
+
signInResolver,
|
|
1677
|
+
authHandler
|
|
1678
|
+
});
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
});
|
|
1682
|
+
const createOauth2ProxyProvider = oauth2Proxy.create;
|
|
2031
1683
|
|
|
2032
1684
|
class OidcAuthProvider {
|
|
2033
1685
|
constructor(options) {
|
|
@@ -2036,9 +1688,7 @@ class OidcAuthProvider {
|
|
|
2036
1688
|
this.prompt = options.prompt;
|
|
2037
1689
|
this.signInResolver = options.signInResolver;
|
|
2038
1690
|
this.authHandler = options.authHandler;
|
|
2039
|
-
this.
|
|
2040
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2041
|
-
this.logger = options.logger;
|
|
1691
|
+
this.resolverContext = options.resolverContext;
|
|
2042
1692
|
}
|
|
2043
1693
|
async start(req) {
|
|
2044
1694
|
const { strategy } = await this.implementation;
|
|
@@ -2098,12 +1748,7 @@ class OidcAuthProvider {
|
|
|
2098
1748
|
return { strategy, client };
|
|
2099
1749
|
}
|
|
2100
1750
|
async handleResult(result) {
|
|
2101
|
-
const
|
|
2102
|
-
logger: this.logger,
|
|
2103
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2104
|
-
tokenIssuer: this.tokenIssuer
|
|
2105
|
-
};
|
|
2106
|
-
const { profile } = await this.authHandler(result, context);
|
|
1751
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2107
1752
|
const response = {
|
|
2108
1753
|
providerInfo: {
|
|
2109
1754
|
idToken: result.tokenset.id_token,
|
|
@@ -2117,92 +1762,55 @@ class OidcAuthProvider {
|
|
|
2117
1762
|
response.backstageIdentity = await this.signInResolver({
|
|
2118
1763
|
result,
|
|
2119
1764
|
profile
|
|
2120
|
-
},
|
|
1765
|
+
}, this.resolverContext);
|
|
2121
1766
|
}
|
|
2122
1767
|
return response;
|
|
2123
1768
|
}
|
|
2124
1769
|
}
|
|
2125
|
-
const
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
};
|
|
2144
|
-
const
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
const scope = envConfig.getOptionalString("scope");
|
|
2162
|
-
const prompt = envConfig.getOptionalString("prompt");
|
|
2163
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2164
|
-
catalogApi,
|
|
2165
|
-
tokenManager
|
|
2166
|
-
});
|
|
2167
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
|
|
2168
|
-
profile: {
|
|
2169
|
-
displayName: userinfo.name,
|
|
2170
|
-
email: userinfo.email,
|
|
2171
|
-
picture: userinfo.picture
|
|
2172
|
-
}
|
|
2173
|
-
});
|
|
2174
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oidcDefaultSignInResolver;
|
|
2175
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
2176
|
-
catalogIdentityClient,
|
|
2177
|
-
tokenIssuer,
|
|
2178
|
-
logger
|
|
2179
|
-
});
|
|
2180
|
-
const provider = new OidcAuthProvider({
|
|
2181
|
-
clientId,
|
|
2182
|
-
clientSecret,
|
|
2183
|
-
callbackUrl,
|
|
2184
|
-
tokenSignedResponseAlg,
|
|
2185
|
-
metadataUrl,
|
|
2186
|
-
scope,
|
|
2187
|
-
prompt,
|
|
2188
|
-
signInResolver,
|
|
2189
|
-
authHandler,
|
|
2190
|
-
logger,
|
|
2191
|
-
tokenIssuer,
|
|
2192
|
-
catalogIdentityClient
|
|
2193
|
-
});
|
|
2194
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2195
|
-
disableRefresh: false,
|
|
2196
|
-
providerId,
|
|
2197
|
-
tokenIssuer,
|
|
2198
|
-
callbackUrl
|
|
1770
|
+
const oidc = createAuthProviderIntegration({
|
|
1771
|
+
create(options) {
|
|
1772
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1773
|
+
var _a;
|
|
1774
|
+
const clientId = envConfig.getString("clientId");
|
|
1775
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1776
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1777
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1778
|
+
const metadataUrl = envConfig.getString("metadataUrl");
|
|
1779
|
+
const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
|
|
1780
|
+
const scope = envConfig.getOptionalString("scope");
|
|
1781
|
+
const prompt = envConfig.getOptionalString("prompt");
|
|
1782
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
|
|
1783
|
+
profile: {
|
|
1784
|
+
displayName: userinfo.name,
|
|
1785
|
+
email: userinfo.email,
|
|
1786
|
+
picture: userinfo.picture
|
|
1787
|
+
}
|
|
1788
|
+
});
|
|
1789
|
+
const provider = new OidcAuthProvider({
|
|
1790
|
+
clientId,
|
|
1791
|
+
clientSecret,
|
|
1792
|
+
callbackUrl,
|
|
1793
|
+
tokenSignedResponseAlg,
|
|
1794
|
+
metadataUrl,
|
|
1795
|
+
scope,
|
|
1796
|
+
prompt,
|
|
1797
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
1798
|
+
authHandler,
|
|
1799
|
+
resolverContext
|
|
1800
|
+
});
|
|
1801
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1802
|
+
disableRefresh: false,
|
|
1803
|
+
providerId,
|
|
1804
|
+
callbackUrl
|
|
1805
|
+
});
|
|
2199
1806
|
});
|
|
2200
|
-
}
|
|
2201
|
-
};
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
const createOidcProvider = oidc.create;
|
|
2202
1810
|
|
|
2203
1811
|
class OktaAuthProvider {
|
|
2204
1812
|
constructor(options) {
|
|
2205
|
-
this.
|
|
1813
|
+
this.store = {
|
|
2206
1814
|
store(_req, cb) {
|
|
2207
1815
|
cb(null, null);
|
|
2208
1816
|
},
|
|
@@ -2210,18 +1818,16 @@ class OktaAuthProvider {
|
|
|
2210
1818
|
cb(null, true);
|
|
2211
1819
|
}
|
|
2212
1820
|
};
|
|
2213
|
-
this.
|
|
2214
|
-
this.
|
|
2215
|
-
this.
|
|
2216
|
-
this.
|
|
2217
|
-
this._logger = options.logger;
|
|
2218
|
-
this._strategy = new passportOktaOauth.Strategy({
|
|
1821
|
+
this.signInResolver = options.signInResolver;
|
|
1822
|
+
this.authHandler = options.authHandler;
|
|
1823
|
+
this.resolverContext = options.resolverContext;
|
|
1824
|
+
this.strategy = new passportOktaOauth.Strategy({
|
|
2219
1825
|
clientID: options.clientId,
|
|
2220
1826
|
clientSecret: options.clientSecret,
|
|
2221
1827
|
callbackURL: options.callbackUrl,
|
|
2222
1828
|
audience: options.audience,
|
|
2223
1829
|
passReqToCallback: false,
|
|
2224
|
-
store: this.
|
|
1830
|
+
store: this.store,
|
|
2225
1831
|
response_type: "code"
|
|
2226
1832
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
2227
1833
|
done(void 0, {
|
|
@@ -2235,7 +1841,7 @@ class OktaAuthProvider {
|
|
|
2235
1841
|
});
|
|
2236
1842
|
}
|
|
2237
1843
|
async start(req) {
|
|
2238
|
-
return await executeRedirectStrategy(req, this.
|
|
1844
|
+
return await executeRedirectStrategy(req, this.strategy, {
|
|
2239
1845
|
accessType: "offline",
|
|
2240
1846
|
prompt: "consent",
|
|
2241
1847
|
scope: req.scope,
|
|
@@ -2243,15 +1849,15 @@ class OktaAuthProvider {
|
|
|
2243
1849
|
});
|
|
2244
1850
|
}
|
|
2245
1851
|
async handler(req) {
|
|
2246
|
-
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.
|
|
1852
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2247
1853
|
return {
|
|
2248
1854
|
response: await this.handleResult(result),
|
|
2249
1855
|
refreshToken: privateInfo.refreshToken
|
|
2250
1856
|
};
|
|
2251
1857
|
}
|
|
2252
1858
|
async refresh(req) {
|
|
2253
|
-
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(this.
|
|
2254
|
-
const fullProfile = await executeFetchUserProfileStrategy(this.
|
|
1859
|
+
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(this.strategy, req.refreshToken, req.scope);
|
|
1860
|
+
const fullProfile = await executeFetchUserProfileStrategy(this.strategy, accessToken);
|
|
2255
1861
|
return {
|
|
2256
1862
|
response: await this.handleResult({
|
|
2257
1863
|
fullProfile,
|
|
@@ -2262,12 +1868,7 @@ class OktaAuthProvider {
|
|
|
2262
1868
|
};
|
|
2263
1869
|
}
|
|
2264
1870
|
async handleResult(result) {
|
|
2265
|
-
const
|
|
2266
|
-
logger: this._logger,
|
|
2267
|
-
catalogIdentityClient: this._catalogIdentityClient,
|
|
2268
|
-
tokenIssuer: this._tokenIssuer
|
|
2269
|
-
};
|
|
2270
|
-
const { profile } = await this._authHandler(result, context);
|
|
1871
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2271
1872
|
const response = {
|
|
2272
1873
|
providerInfo: {
|
|
2273
1874
|
idToken: result.params.id_token,
|
|
@@ -2277,107 +1878,70 @@ class OktaAuthProvider {
|
|
|
2277
1878
|
},
|
|
2278
1879
|
profile
|
|
2279
1880
|
};
|
|
2280
|
-
if (this.
|
|
2281
|
-
response.backstageIdentity = await this.
|
|
1881
|
+
if (this.signInResolver) {
|
|
1882
|
+
response.backstageIdentity = await this.signInResolver({
|
|
2282
1883
|
result,
|
|
2283
1884
|
profile
|
|
2284
|
-
},
|
|
1885
|
+
}, this.resolverContext);
|
|
2285
1886
|
}
|
|
2286
1887
|
return response;
|
|
2287
1888
|
}
|
|
2288
1889
|
}
|
|
2289
|
-
const
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
1890
|
+
const okta = createAuthProviderIntegration({
|
|
1891
|
+
create(options) {
|
|
1892
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1893
|
+
var _a;
|
|
1894
|
+
const clientId = envConfig.getString("clientId");
|
|
1895
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1896
|
+
const audience = envConfig.getString("audience");
|
|
1897
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1898
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1899
|
+
if (!audience.startsWith("https://")) {
|
|
1900
|
+
throw new Error("URL for 'audience' must start with 'https://'.");
|
|
1901
|
+
}
|
|
1902
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1903
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1904
|
+
});
|
|
1905
|
+
const provider = new OktaAuthProvider({
|
|
1906
|
+
audience,
|
|
1907
|
+
clientId,
|
|
1908
|
+
clientSecret,
|
|
1909
|
+
callbackUrl,
|
|
1910
|
+
authHandler,
|
|
1911
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
1912
|
+
resolverContext
|
|
1913
|
+
});
|
|
1914
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1915
|
+
disableRefresh: false,
|
|
1916
|
+
providerId,
|
|
1917
|
+
callbackUrl
|
|
1918
|
+
});
|
|
1919
|
+
});
|
|
1920
|
+
},
|
|
1921
|
+
resolvers: {
|
|
1922
|
+
emailMatchingUserEntityAnnotation() {
|
|
1923
|
+
return async (info, ctx) => {
|
|
1924
|
+
const { profile } = info;
|
|
1925
|
+
if (!profile.email) {
|
|
1926
|
+
throw new Error("Okta profile contained no email");
|
|
1927
|
+
}
|
|
1928
|
+
return ctx.signInWithCatalogUser({
|
|
1929
|
+
annotations: {
|
|
1930
|
+
"okta.com/email": profile.email
|
|
1931
|
+
}
|
|
1932
|
+
});
|
|
1933
|
+
};
|
|
2297
1934
|
}
|
|
2298
|
-
});
|
|
2299
|
-
const claims = getEntityClaims(entity);
|
|
2300
|
-
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
2301
|
-
return { id: entity.metadata.name, entity, token };
|
|
2302
|
-
};
|
|
2303
|
-
const oktaDefaultSignInResolver = async (info, ctx) => {
|
|
2304
|
-
const { profile } = info;
|
|
2305
|
-
if (!profile.email) {
|
|
2306
|
-
throw new Error("Okta profile contained no email");
|
|
2307
1935
|
}
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
namespace: catalogModel.DEFAULT_NAMESPACE,
|
|
2312
|
-
name: userId
|
|
2313
|
-
});
|
|
2314
|
-
const token = await ctx.tokenIssuer.issueToken({
|
|
2315
|
-
claims: {
|
|
2316
|
-
sub: entityRef,
|
|
2317
|
-
ent: [entityRef]
|
|
2318
|
-
}
|
|
2319
|
-
});
|
|
2320
|
-
return { id: userId, token };
|
|
2321
|
-
};
|
|
2322
|
-
const createOktaProvider = (_options) => {
|
|
2323
|
-
return ({
|
|
2324
|
-
providerId,
|
|
2325
|
-
globalConfig,
|
|
2326
|
-
config,
|
|
2327
|
-
tokenIssuer,
|
|
2328
|
-
tokenManager,
|
|
2329
|
-
catalogApi,
|
|
2330
|
-
logger
|
|
2331
|
-
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2332
|
-
var _a, _b;
|
|
2333
|
-
const clientId = envConfig.getString("clientId");
|
|
2334
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
2335
|
-
const audience = envConfig.getString("audience");
|
|
2336
|
-
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
2337
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
2338
|
-
if (!audience.startsWith("https://")) {
|
|
2339
|
-
throw new Error("URL for 'audience' must start with 'https://'.");
|
|
2340
|
-
}
|
|
2341
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2342
|
-
catalogApi,
|
|
2343
|
-
tokenManager
|
|
2344
|
-
});
|
|
2345
|
-
const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({ fullProfile, params }) => ({
|
|
2346
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
2347
|
-
});
|
|
2348
|
-
const signInResolverFn = (_b = (_a = _options == null ? void 0 : _options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oktaDefaultSignInResolver;
|
|
2349
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
2350
|
-
catalogIdentityClient,
|
|
2351
|
-
tokenIssuer,
|
|
2352
|
-
logger
|
|
2353
|
-
});
|
|
2354
|
-
const provider = new OktaAuthProvider({
|
|
2355
|
-
audience,
|
|
2356
|
-
clientId,
|
|
2357
|
-
clientSecret,
|
|
2358
|
-
callbackUrl,
|
|
2359
|
-
authHandler,
|
|
2360
|
-
signInResolver,
|
|
2361
|
-
tokenIssuer,
|
|
2362
|
-
catalogIdentityClient,
|
|
2363
|
-
logger
|
|
2364
|
-
});
|
|
2365
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2366
|
-
disableRefresh: false,
|
|
2367
|
-
providerId,
|
|
2368
|
-
tokenIssuer,
|
|
2369
|
-
callbackUrl
|
|
2370
|
-
});
|
|
2371
|
-
});
|
|
2372
|
-
};
|
|
1936
|
+
});
|
|
1937
|
+
const createOktaProvider = okta.create;
|
|
1938
|
+
const oktaEmailSignInResolver = okta.resolvers.emailMatchingUserEntityAnnotation();
|
|
2373
1939
|
|
|
2374
1940
|
class OneLoginProvider {
|
|
2375
1941
|
constructor(options) {
|
|
2376
1942
|
this.signInResolver = options.signInResolver;
|
|
2377
1943
|
this.authHandler = options.authHandler;
|
|
2378
|
-
this.
|
|
2379
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2380
|
-
this.logger = options.logger;
|
|
1944
|
+
this.resolverContext = options.resolverContext;
|
|
2381
1945
|
this._strategy = new passportOneloginOauth.Strategy({
|
|
2382
1946
|
issuer: options.issuer,
|
|
2383
1947
|
clientID: options.clientId,
|
|
@@ -2423,12 +1987,7 @@ class OneLoginProvider {
|
|
|
2423
1987
|
};
|
|
2424
1988
|
}
|
|
2425
1989
|
async handleResult(result) {
|
|
2426
|
-
const
|
|
2427
|
-
logger: this.logger,
|
|
2428
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2429
|
-
tokenIssuer: this.tokenIssuer
|
|
2430
|
-
};
|
|
2431
|
-
const { profile } = await this.authHandler(result, context);
|
|
1990
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2432
1991
|
const response = {
|
|
2433
1992
|
providerInfo: {
|
|
2434
1993
|
idToken: result.params.id_token,
|
|
@@ -2442,71 +2001,48 @@ class OneLoginProvider {
|
|
|
2442
2001
|
response.backstageIdentity = await this.signInResolver({
|
|
2443
2002
|
result,
|
|
2444
2003
|
profile
|
|
2445
|
-
},
|
|
2004
|
+
}, this.resolverContext);
|
|
2446
2005
|
}
|
|
2447
2006
|
return response;
|
|
2448
2007
|
}
|
|
2449
2008
|
}
|
|
2450
|
-
const
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
const
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
tokenManager
|
|
2477
|
-
});
|
|
2478
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
2479
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
2480
|
-
});
|
|
2481
|
-
const signInResolver = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : defaultSignInResolver;
|
|
2482
|
-
const provider = new OneLoginProvider({
|
|
2483
|
-
clientId,
|
|
2484
|
-
clientSecret,
|
|
2485
|
-
callbackUrl,
|
|
2486
|
-
issuer,
|
|
2487
|
-
authHandler,
|
|
2488
|
-
signInResolver,
|
|
2489
|
-
tokenIssuer,
|
|
2490
|
-
catalogIdentityClient,
|
|
2491
|
-
logger
|
|
2492
|
-
});
|
|
2493
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2494
|
-
disableRefresh: false,
|
|
2495
|
-
providerId,
|
|
2496
|
-
tokenIssuer,
|
|
2497
|
-
callbackUrl
|
|
2009
|
+
const onelogin = createAuthProviderIntegration({
|
|
2010
|
+
create(options) {
|
|
2011
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2012
|
+
var _a;
|
|
2013
|
+
const clientId = envConfig.getString("clientId");
|
|
2014
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
2015
|
+
const issuer = envConfig.getString("issuer");
|
|
2016
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
2017
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
2018
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
2019
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
2020
|
+
});
|
|
2021
|
+
const provider = new OneLoginProvider({
|
|
2022
|
+
clientId,
|
|
2023
|
+
clientSecret,
|
|
2024
|
+
callbackUrl,
|
|
2025
|
+
issuer,
|
|
2026
|
+
authHandler,
|
|
2027
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
2028
|
+
resolverContext
|
|
2029
|
+
});
|
|
2030
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2031
|
+
disableRefresh: false,
|
|
2032
|
+
providerId,
|
|
2033
|
+
callbackUrl
|
|
2034
|
+
});
|
|
2498
2035
|
});
|
|
2499
|
-
}
|
|
2500
|
-
};
|
|
2036
|
+
}
|
|
2037
|
+
});
|
|
2038
|
+
const createOneLoginProvider = onelogin.create;
|
|
2501
2039
|
|
|
2502
2040
|
class SamlAuthProvider {
|
|
2503
2041
|
constructor(options) {
|
|
2504
2042
|
this.appUrl = options.appUrl;
|
|
2505
2043
|
this.signInResolver = options.signInResolver;
|
|
2506
2044
|
this.authHandler = options.authHandler;
|
|
2507
|
-
this.
|
|
2508
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2509
|
-
this.logger = options.logger;
|
|
2045
|
+
this.resolverContext = options.resolverContext;
|
|
2510
2046
|
this.strategy = new passportSaml.Strategy({ ...options }, (fullProfile, done) => {
|
|
2511
2047
|
done(void 0, { fullProfile });
|
|
2512
2048
|
});
|
|
@@ -2517,13 +2053,8 @@ class SamlAuthProvider {
|
|
|
2517
2053
|
}
|
|
2518
2054
|
async frameHandler(req, res) {
|
|
2519
2055
|
try {
|
|
2520
|
-
const context = {
|
|
2521
|
-
logger: this.logger,
|
|
2522
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2523
|
-
tokenIssuer: this.tokenIssuer
|
|
2524
|
-
};
|
|
2525
2056
|
const { result } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2526
|
-
const { profile } = await this.authHandler(result,
|
|
2057
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2527
2058
|
const response = {
|
|
2528
2059
|
profile,
|
|
2529
2060
|
providerInfo: {}
|
|
@@ -2532,7 +2063,7 @@ class SamlAuthProvider {
|
|
|
2532
2063
|
const signInResponse = await this.signInResolver({
|
|
2533
2064
|
result,
|
|
2534
2065
|
profile
|
|
2535
|
-
},
|
|
2066
|
+
}, this.resolverContext);
|
|
2536
2067
|
response.backstageIdentity = prepareBackstageIdentityResponse(signInResponse);
|
|
2537
2068
|
}
|
|
2538
2069
|
return postMessageResponse(res, this.appUrl, {
|
|
@@ -2551,71 +2082,53 @@ class SamlAuthProvider {
|
|
|
2551
2082
|
res.end();
|
|
2552
2083
|
}
|
|
2553
2084
|
}
|
|
2554
|
-
const
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2085
|
+
const saml = createAuthProviderIntegration({
|
|
2086
|
+
create(options) {
|
|
2087
|
+
return ({ providerId, globalConfig, config, resolverContext }) => {
|
|
2088
|
+
var _a;
|
|
2089
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2090
|
+
profile: {
|
|
2091
|
+
email: fullProfile.email,
|
|
2092
|
+
displayName: fullProfile.displayName
|
|
2093
|
+
}
|
|
2094
|
+
});
|
|
2095
|
+
return new SamlAuthProvider({
|
|
2096
|
+
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
|
2097
|
+
entryPoint: config.getString("entryPoint"),
|
|
2098
|
+
logoutUrl: config.getOptionalString("logoutUrl"),
|
|
2099
|
+
audience: config.getOptionalString("audience"),
|
|
2100
|
+
issuer: config.getString("issuer"),
|
|
2101
|
+
cert: config.getString("cert"),
|
|
2102
|
+
privateKey: config.getOptionalString("privateKey"),
|
|
2103
|
+
authnContext: config.getOptionalStringArray("authnContext"),
|
|
2104
|
+
identifierFormat: config.getOptionalString("identifierFormat"),
|
|
2105
|
+
decryptionPvk: config.getOptionalString("decryptionPvk"),
|
|
2106
|
+
signatureAlgorithm: config.getOptionalString("signatureAlgorithm"),
|
|
2107
|
+
digestAlgorithm: config.getOptionalString("digestAlgorithm"),
|
|
2108
|
+
acceptedClockSkewMs: config.getOptionalNumber("acceptedClockSkewMs"),
|
|
2109
|
+
appUrl: globalConfig.appUrl,
|
|
2110
|
+
authHandler,
|
|
2111
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
2112
|
+
resolverContext
|
|
2113
|
+
});
|
|
2114
|
+
};
|
|
2115
|
+
},
|
|
2116
|
+
resolvers: {
|
|
2117
|
+
nameIdMatchingUserEntityName() {
|
|
2118
|
+
return async (info, ctx) => {
|
|
2119
|
+
const id = info.result.fullProfile.nameID;
|
|
2120
|
+
if (!id) {
|
|
2121
|
+
throw new errors.AuthenticationError("No nameID found in SAML response");
|
|
2122
|
+
}
|
|
2123
|
+
return ctx.signInWithCatalogUser({
|
|
2124
|
+
entityRef: { name: id }
|
|
2125
|
+
});
|
|
2126
|
+
};
|
|
2565
2127
|
}
|
|
2566
|
-
}
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
const
|
|
2570
|
-
return ({
|
|
2571
|
-
providerId,
|
|
2572
|
-
globalConfig,
|
|
2573
|
-
config,
|
|
2574
|
-
tokenIssuer,
|
|
2575
|
-
tokenManager,
|
|
2576
|
-
catalogApi,
|
|
2577
|
-
logger
|
|
2578
|
-
}) => {
|
|
2579
|
-
var _a, _b;
|
|
2580
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2581
|
-
catalogApi,
|
|
2582
|
-
tokenManager
|
|
2583
|
-
});
|
|
2584
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2585
|
-
profile: {
|
|
2586
|
-
email: fullProfile.email,
|
|
2587
|
-
displayName: fullProfile.displayName
|
|
2588
|
-
}
|
|
2589
|
-
});
|
|
2590
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : samlDefaultSignInResolver;
|
|
2591
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
2592
|
-
catalogIdentityClient,
|
|
2593
|
-
tokenIssuer,
|
|
2594
|
-
logger
|
|
2595
|
-
});
|
|
2596
|
-
return new SamlAuthProvider({
|
|
2597
|
-
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
|
2598
|
-
entryPoint: config.getString("entryPoint"),
|
|
2599
|
-
logoutUrl: config.getOptionalString("logoutUrl"),
|
|
2600
|
-
audience: config.getOptionalString("audience"),
|
|
2601
|
-
issuer: config.getString("issuer"),
|
|
2602
|
-
cert: config.getString("cert"),
|
|
2603
|
-
privateKey: config.getOptionalString("privateKey"),
|
|
2604
|
-
authnContext: config.getOptionalStringArray("authnContext"),
|
|
2605
|
-
identifierFormat: config.getOptionalString("identifierFormat"),
|
|
2606
|
-
decryptionPvk: config.getOptionalString("decryptionPvk"),
|
|
2607
|
-
signatureAlgorithm: config.getOptionalString("signatureAlgorithm"),
|
|
2608
|
-
digestAlgorithm: config.getOptionalString("digestAlgorithm"),
|
|
2609
|
-
acceptedClockSkewMs: config.getOptionalNumber("acceptedClockSkewMs"),
|
|
2610
|
-
tokenIssuer,
|
|
2611
|
-
appUrl: globalConfig.appUrl,
|
|
2612
|
-
authHandler,
|
|
2613
|
-
signInResolver,
|
|
2614
|
-
logger,
|
|
2615
|
-
catalogIdentityClient
|
|
2616
|
-
});
|
|
2617
|
-
};
|
|
2618
|
-
};
|
|
2128
|
+
}
|
|
2129
|
+
});
|
|
2130
|
+
const createSamlProvider = saml.create;
|
|
2131
|
+
const samlNameIdEntityNameSignInResolver = saml.resolvers.nameIdMatchingUserEntityName();
|
|
2619
2132
|
|
|
2620
2133
|
const IAP_JWT_HEADER = "x-goog-iap-jwt-assertion";
|
|
2621
2134
|
|
|
@@ -2661,9 +2174,7 @@ class GcpIapProvider {
|
|
|
2661
2174
|
this.authHandler = options.authHandler;
|
|
2662
2175
|
this.signInResolver = options.signInResolver;
|
|
2663
2176
|
this.tokenValidator = options.tokenValidator;
|
|
2664
|
-
this.
|
|
2665
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2666
|
-
this.logger = options.logger;
|
|
2177
|
+
this.resolverContext = options.resolverContext;
|
|
2667
2178
|
}
|
|
2668
2179
|
async start() {
|
|
2669
2180
|
}
|
|
@@ -2671,13 +2182,8 @@ class GcpIapProvider {
|
|
|
2671
2182
|
}
|
|
2672
2183
|
async refresh(req, res) {
|
|
2673
2184
|
const result = await parseRequestToken(req.header(IAP_JWT_HEADER), this.tokenValidator);
|
|
2674
|
-
const
|
|
2675
|
-
|
|
2676
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2677
|
-
tokenIssuer: this.tokenIssuer
|
|
2678
|
-
};
|
|
2679
|
-
const { profile } = await this.authHandler(result, context);
|
|
2680
|
-
const backstageIdentity = await this.signInResolver({ profile, result }, context);
|
|
2185
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2186
|
+
const backstageIdentity = await this.signInResolver({ profile, result }, this.resolverContext);
|
|
2681
2187
|
const response = {
|
|
2682
2188
|
providerInfo: { iapToken: result.iapToken },
|
|
2683
2189
|
profile,
|
|
@@ -2686,27 +2192,42 @@ class GcpIapProvider {
|
|
|
2686
2192
|
res.json(response);
|
|
2687
2193
|
}
|
|
2688
2194
|
}
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2195
|
+
const gcpIap = createAuthProviderIntegration({
|
|
2196
|
+
create(options) {
|
|
2197
|
+
return ({ config, resolverContext }) => {
|
|
2198
|
+
var _a;
|
|
2199
|
+
const audience = config.getString("audience");
|
|
2200
|
+
const authHandler = (_a = options.authHandler) != null ? _a : defaultAuthHandler;
|
|
2201
|
+
const signInResolver = options.signIn.resolver;
|
|
2202
|
+
const tokenValidator = createTokenValidator(audience);
|
|
2203
|
+
return new GcpIapProvider({
|
|
2204
|
+
authHandler,
|
|
2205
|
+
signInResolver,
|
|
2206
|
+
tokenValidator,
|
|
2207
|
+
resolverContext
|
|
2208
|
+
});
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
});
|
|
2212
|
+
const createGcpIapProvider = gcpIap.create;
|
|
2213
|
+
|
|
2214
|
+
const providers = Object.freeze({
|
|
2215
|
+
atlassian,
|
|
2216
|
+
auth0,
|
|
2217
|
+
awsAlb,
|
|
2218
|
+
bitbucket,
|
|
2219
|
+
gcpIap,
|
|
2220
|
+
github,
|
|
2221
|
+
gitlab,
|
|
2222
|
+
google,
|
|
2223
|
+
microsoft,
|
|
2224
|
+
oauth2,
|
|
2225
|
+
oauth2Proxy,
|
|
2226
|
+
oidc,
|
|
2227
|
+
okta,
|
|
2228
|
+
onelogin,
|
|
2229
|
+
saml
|
|
2230
|
+
});
|
|
2710
2231
|
|
|
2711
2232
|
const factories = {
|
|
2712
2233
|
google: createGoogleProvider(),
|
|
@@ -2994,6 +2515,149 @@ class KeyStores {
|
|
|
2994
2515
|
}
|
|
2995
2516
|
}
|
|
2996
2517
|
|
|
2518
|
+
class CatalogIdentityClient {
|
|
2519
|
+
constructor(options) {
|
|
2520
|
+
this.catalogApi = options.catalogApi;
|
|
2521
|
+
this.tokenManager = options.tokenManager;
|
|
2522
|
+
}
|
|
2523
|
+
async findUser(query) {
|
|
2524
|
+
const filter = {
|
|
2525
|
+
kind: "user"
|
|
2526
|
+
};
|
|
2527
|
+
for (const [key, value] of Object.entries(query.annotations)) {
|
|
2528
|
+
filter[`metadata.annotations.${key}`] = value;
|
|
2529
|
+
}
|
|
2530
|
+
const { token } = await this.tokenManager.getToken();
|
|
2531
|
+
const { items } = await this.catalogApi.getEntities({ filter }, { token });
|
|
2532
|
+
if (items.length !== 1) {
|
|
2533
|
+
if (items.length > 1) {
|
|
2534
|
+
throw new errors.ConflictError("User lookup resulted in multiple matches");
|
|
2535
|
+
} else {
|
|
2536
|
+
throw new errors.NotFoundError("User not found");
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
return items[0];
|
|
2540
|
+
}
|
|
2541
|
+
async resolveCatalogMembership(query) {
|
|
2542
|
+
const { entityRefs, logger } = query;
|
|
2543
|
+
const resolvedEntityRefs = entityRefs.map((ref) => {
|
|
2544
|
+
try {
|
|
2545
|
+
const parsedRef = catalogModel.parseEntityRef(ref.toLocaleLowerCase("en-US"), {
|
|
2546
|
+
defaultKind: "user",
|
|
2547
|
+
defaultNamespace: "default"
|
|
2548
|
+
});
|
|
2549
|
+
return parsedRef;
|
|
2550
|
+
} catch {
|
|
2551
|
+
logger == null ? void 0 : logger.warn(`Failed to parse entityRef from ${ref}, ignoring`);
|
|
2552
|
+
return null;
|
|
2553
|
+
}
|
|
2554
|
+
}).filter((ref) => ref !== null);
|
|
2555
|
+
const filter = resolvedEntityRefs.map((ref) => ({
|
|
2556
|
+
kind: ref.kind,
|
|
2557
|
+
"metadata.namespace": ref.namespace,
|
|
2558
|
+
"metadata.name": ref.name
|
|
2559
|
+
}));
|
|
2560
|
+
const { token } = await this.tokenManager.getToken();
|
|
2561
|
+
const entities = await this.catalogApi.getEntities({ filter }, { token }).then((r) => r.items);
|
|
2562
|
+
if (entityRefs.length !== entities.length) {
|
|
2563
|
+
const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
|
|
2564
|
+
const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
|
|
2565
|
+
logger == null ? void 0 : logger.debug(`Entities not found for refs ${missingEntityNames.join()}`);
|
|
2566
|
+
}
|
|
2567
|
+
const memberOf = entities.flatMap((e) => {
|
|
2568
|
+
var _a, _b;
|
|
2569
|
+
return (_b = (_a = e.relations) == null ? void 0 : _a.filter((r) => r.type === catalogModel.RELATION_MEMBER_OF).map((r) => r.targetRef)) != null ? _b : [];
|
|
2570
|
+
});
|
|
2571
|
+
const newEntityRefs = [
|
|
2572
|
+
...new Set(resolvedEntityRefs.map(catalogModel.stringifyEntityRef).concat(memberOf))
|
|
2573
|
+
];
|
|
2574
|
+
logger == null ? void 0 : logger.debug(`Found catalog membership: ${newEntityRefs.join()}`);
|
|
2575
|
+
return newEntityRefs;
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
function getEntityClaims(entity) {
|
|
2580
|
+
var _a, _b;
|
|
2581
|
+
const userRef = catalogModel.stringifyEntityRef(entity);
|
|
2582
|
+
const membershipRefs = (_b = (_a = entity.relations) == null ? void 0 : _a.filter((r) => r.type === catalogModel.RELATION_MEMBER_OF && r.targetRef.startsWith("group:")).map((r) => r.targetRef)) != null ? _b : [];
|
|
2583
|
+
return {
|
|
2584
|
+
sub: userRef,
|
|
2585
|
+
ent: [userRef, ...membershipRefs]
|
|
2586
|
+
};
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2589
|
+
function getDefaultOwnershipEntityRefs(entity) {
|
|
2590
|
+
var _a, _b;
|
|
2591
|
+
const membershipRefs = (_b = (_a = entity.relations) == null ? void 0 : _a.filter((r) => r.type === catalogModel.RELATION_MEMBER_OF && r.targetRef.startsWith("group:")).map((r) => r.targetRef)) != null ? _b : [];
|
|
2592
|
+
return Array.from(/* @__PURE__ */ new Set([catalogModel.stringifyEntityRef(entity), ...membershipRefs]));
|
|
2593
|
+
}
|
|
2594
|
+
class CatalogAuthResolverContext {
|
|
2595
|
+
constructor(logger, tokenIssuer, catalogIdentityClient, catalogApi, tokenManager) {
|
|
2596
|
+
this.logger = logger;
|
|
2597
|
+
this.tokenIssuer = tokenIssuer;
|
|
2598
|
+
this.catalogIdentityClient = catalogIdentityClient;
|
|
2599
|
+
this.catalogApi = catalogApi;
|
|
2600
|
+
this.tokenManager = tokenManager;
|
|
2601
|
+
}
|
|
2602
|
+
static create(options) {
|
|
2603
|
+
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2604
|
+
catalogApi: options.catalogApi,
|
|
2605
|
+
tokenManager: options.tokenManager
|
|
2606
|
+
});
|
|
2607
|
+
return new CatalogAuthResolverContext(options.logger, options.tokenIssuer, catalogIdentityClient, options.catalogApi, options.tokenManager);
|
|
2608
|
+
}
|
|
2609
|
+
async issueToken(params) {
|
|
2610
|
+
const token = await this.tokenIssuer.issueToken(params);
|
|
2611
|
+
return { token };
|
|
2612
|
+
}
|
|
2613
|
+
async findCatalogUser(query) {
|
|
2614
|
+
let result = void 0;
|
|
2615
|
+
const { token } = await this.tokenManager.getToken();
|
|
2616
|
+
if ("entityRef" in query) {
|
|
2617
|
+
const entityRef = catalogModel.parseEntityRef(query.entityRef, {
|
|
2618
|
+
defaultKind: "User",
|
|
2619
|
+
defaultNamespace: catalogModel.DEFAULT_NAMESPACE
|
|
2620
|
+
});
|
|
2621
|
+
result = await this.catalogApi.getEntityByRef(entityRef, { token });
|
|
2622
|
+
} else if ("annotations" in query) {
|
|
2623
|
+
const filter = {
|
|
2624
|
+
kind: "user"
|
|
2625
|
+
};
|
|
2626
|
+
for (const [key, value] of Object.entries(query.annotations)) {
|
|
2627
|
+
filter[`metadata.annotations.${key}`] = value;
|
|
2628
|
+
}
|
|
2629
|
+
const res = await this.catalogApi.getEntities({ filter }, { token });
|
|
2630
|
+
result = res.items;
|
|
2631
|
+
} else if ("filter" in query) {
|
|
2632
|
+
const res = await this.catalogApi.getEntities({ filter: query.filter }, { token });
|
|
2633
|
+
result = res.items;
|
|
2634
|
+
} else {
|
|
2635
|
+
throw new errors.InputError("Invalid user lookup query");
|
|
2636
|
+
}
|
|
2637
|
+
if (Array.isArray(result)) {
|
|
2638
|
+
if (result.length > 1) {
|
|
2639
|
+
throw new errors.ConflictError("User lookup resulted in multiple matches");
|
|
2640
|
+
}
|
|
2641
|
+
result = result[0];
|
|
2642
|
+
}
|
|
2643
|
+
if (!result) {
|
|
2644
|
+
throw new errors.NotFoundError("User not found");
|
|
2645
|
+
}
|
|
2646
|
+
return { entity: result };
|
|
2647
|
+
}
|
|
2648
|
+
async signInWithCatalogUser(query) {
|
|
2649
|
+
const { entity } = await this.findCatalogUser(query);
|
|
2650
|
+
const ownershipRefs = getDefaultOwnershipEntityRefs(entity);
|
|
2651
|
+
const token = await this.tokenIssuer.issueToken({
|
|
2652
|
+
claims: {
|
|
2653
|
+
sub: catalogModel.stringifyEntityRef(entity),
|
|
2654
|
+
ent: ownershipRefs
|
|
2655
|
+
}
|
|
2656
|
+
});
|
|
2657
|
+
return { token };
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2997
2661
|
async function createRouter(options) {
|
|
2998
2662
|
const {
|
|
2999
2663
|
logger,
|
|
@@ -3055,7 +2719,13 @@ async function createRouter(options) {
|
|
|
3055
2719
|
tokenManager,
|
|
3056
2720
|
tokenIssuer,
|
|
3057
2721
|
discovery,
|
|
3058
|
-
catalogApi
|
|
2722
|
+
catalogApi,
|
|
2723
|
+
resolverContext: CatalogAuthResolverContext.create({
|
|
2724
|
+
logger,
|
|
2725
|
+
catalogApi,
|
|
2726
|
+
tokenIssuer,
|
|
2727
|
+
tokenManager
|
|
2728
|
+
})
|
|
3059
2729
|
});
|
|
3060
2730
|
const r = Router__default["default"]();
|
|
3061
2731
|
r.get("/start", provider.start.bind(provider));
|
|
@@ -3133,12 +2803,15 @@ exports.createSamlProvider = createSamlProvider;
|
|
|
3133
2803
|
exports.defaultAuthProviderFactories = factories;
|
|
3134
2804
|
exports.encodeState = encodeState;
|
|
3135
2805
|
exports.ensuresXRequestedWith = ensuresXRequestedWith;
|
|
2806
|
+
exports.getDefaultOwnershipEntityRefs = getDefaultOwnershipEntityRefs;
|
|
3136
2807
|
exports.getEntityClaims = getEntityClaims;
|
|
3137
2808
|
exports.googleEmailSignInResolver = googleEmailSignInResolver;
|
|
3138
2809
|
exports.microsoftEmailSignInResolver = microsoftEmailSignInResolver;
|
|
3139
2810
|
exports.oktaEmailSignInResolver = oktaEmailSignInResolver;
|
|
3140
2811
|
exports.postMessageResponse = postMessageResponse;
|
|
3141
2812
|
exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
|
|
2813
|
+
exports.providers = providers;
|
|
3142
2814
|
exports.readState = readState;
|
|
2815
|
+
exports.samlNameIdEntityNameSignInResolver = samlNameIdEntityNameSignInResolver;
|
|
3143
2816
|
exports.verifyNonce = verifyNonce;
|
|
3144
2817
|
//# sourceMappingURL=index.cjs.js.map
|