@backstage/plugin-auth-backend 0.12.3 → 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 +156 -0
- package/config.d.ts +3 -0
- package/dist/index.cjs.js +798 -1139
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +634 -64
- package/package.json +9 -9
package/dist/index.cjs.js
CHANGED
|
@@ -10,7 +10,6 @@ var errors = require('@backstage/errors');
|
|
|
10
10
|
var pickBy = require('lodash/pickBy');
|
|
11
11
|
var crypto = require('crypto');
|
|
12
12
|
var url = require('url');
|
|
13
|
-
var catalogModel = require('@backstage/catalog-model');
|
|
14
13
|
var jwtDecoder = require('jwt-decode');
|
|
15
14
|
var fetch = require('node-fetch');
|
|
16
15
|
var NodeCache = require('node-cache');
|
|
@@ -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');
|
|
@@ -255,18 +255,11 @@ function parseJwtPayload(token) {
|
|
|
255
255
|
}
|
|
256
256
|
function prepareBackstageIdentityResponse(result) {
|
|
257
257
|
const { sub, ent } = parseJwtPayload(result.token);
|
|
258
|
-
const userEntityRef = catalogModel.stringifyEntityRef(catalogModel.parseEntityRef(sub, {
|
|
259
|
-
defaultKind: "user",
|
|
260
|
-
defaultNamespace: catalogModel.DEFAULT_NAMESPACE
|
|
261
|
-
}));
|
|
262
258
|
return {
|
|
263
|
-
...
|
|
264
|
-
idToken: result.token,
|
|
265
|
-
...result
|
|
266
|
-
},
|
|
259
|
+
...result,
|
|
267
260
|
identity: {
|
|
268
261
|
type: "user",
|
|
269
|
-
userEntityRef,
|
|
262
|
+
userEntityRef: sub,
|
|
270
263
|
ownershipEntityRefs: ent != null ? ent : []
|
|
271
264
|
}
|
|
272
265
|
};
|
|
@@ -429,17 +422,10 @@ class OAuthAdapter {
|
|
|
429
422
|
if (!identity) {
|
|
430
423
|
return void 0;
|
|
431
424
|
}
|
|
432
|
-
if (identity.token) {
|
|
433
|
-
return
|
|
425
|
+
if (!identity.token) {
|
|
426
|
+
throw new errors.InputError(`Identity response must return a token`);
|
|
434
427
|
}
|
|
435
|
-
|
|
436
|
-
defaultKind: "user",
|
|
437
|
-
defaultNamespace: catalogModel.DEFAULT_NAMESPACE
|
|
438
|
-
}));
|
|
439
|
-
const token = await this.options.tokenIssuer.issueToken({
|
|
440
|
-
claims: { sub: userEntityRef }
|
|
441
|
-
});
|
|
442
|
-
return prepareBackstageIdentityResponse({ ...identity, token });
|
|
428
|
+
return prepareBackstageIdentityResponse(identity);
|
|
443
429
|
}
|
|
444
430
|
}
|
|
445
431
|
|
|
@@ -556,75 +542,12 @@ const executeFetchUserProfileStrategy = async (providerStrategy, accessToken) =>
|
|
|
556
542
|
});
|
|
557
543
|
};
|
|
558
544
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
const filter = {
|
|
566
|
-
kind: "user"
|
|
567
|
-
};
|
|
568
|
-
for (const [key, value] of Object.entries(query.annotations)) {
|
|
569
|
-
filter[`metadata.annotations.${key}`] = value;
|
|
570
|
-
}
|
|
571
|
-
const { token } = await this.tokenManager.getToken();
|
|
572
|
-
const { items } = await this.catalogApi.getEntities({ filter }, { token });
|
|
573
|
-
if (items.length !== 1) {
|
|
574
|
-
if (items.length > 1) {
|
|
575
|
-
throw new errors.ConflictError("User lookup resulted in multiple matches");
|
|
576
|
-
} else {
|
|
577
|
-
throw new errors.NotFoundError("User not found");
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
return items[0];
|
|
581
|
-
}
|
|
582
|
-
async resolveCatalogMembership(query) {
|
|
583
|
-
const { entityRefs, logger } = query;
|
|
584
|
-
const resolvedEntityRefs = entityRefs.map((ref) => {
|
|
585
|
-
try {
|
|
586
|
-
const parsedRef = catalogModel.parseEntityRef(ref.toLocaleLowerCase("en-US"), {
|
|
587
|
-
defaultKind: "user",
|
|
588
|
-
defaultNamespace: "default"
|
|
589
|
-
});
|
|
590
|
-
return parsedRef;
|
|
591
|
-
} catch {
|
|
592
|
-
logger == null ? void 0 : logger.warn(`Failed to parse entityRef from ${ref}, ignoring`);
|
|
593
|
-
return null;
|
|
594
|
-
}
|
|
595
|
-
}).filter((ref) => ref !== null);
|
|
596
|
-
const filter = resolvedEntityRefs.map((ref) => ({
|
|
597
|
-
kind: ref.kind,
|
|
598
|
-
"metadata.namespace": ref.namespace,
|
|
599
|
-
"metadata.name": ref.name
|
|
600
|
-
}));
|
|
601
|
-
const { token } = await this.tokenManager.getToken();
|
|
602
|
-
const entities = await this.catalogApi.getEntities({ filter }, { token }).then((r) => r.items);
|
|
603
|
-
if (entityRefs.length !== entities.length) {
|
|
604
|
-
const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
|
|
605
|
-
const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
|
|
606
|
-
logger == null ? void 0 : logger.debug(`Entities not found for refs ${missingEntityNames.join()}`);
|
|
607
|
-
}
|
|
608
|
-
const memberOf = entities.flatMap((e) => {
|
|
609
|
-
var _a, _b;
|
|
610
|
-
return (_b = (_a = e.relations) == null ? void 0 : _a.filter((r) => r.type === catalogModel.RELATION_MEMBER_OF).map((r) => r.targetRef)) != null ? _b : [];
|
|
611
|
-
});
|
|
612
|
-
const newEntityRefs = [
|
|
613
|
-
...new Set(resolvedEntityRefs.map(catalogModel.stringifyEntityRef).concat(memberOf))
|
|
614
|
-
];
|
|
615
|
-
logger == null ? void 0 : logger.debug(`Found catalog membership: ${newEntityRefs.join()}`);
|
|
616
|
-
return newEntityRefs;
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
function getEntityClaims(entity) {
|
|
621
|
-
var _a, _b;
|
|
622
|
-
const userRef = catalogModel.stringifyEntityRef(entity);
|
|
623
|
-
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 : [];
|
|
624
|
-
return {
|
|
625
|
-
sub: userRef,
|
|
626
|
-
ent: [userRef, ...membershipRefs]
|
|
627
|
-
};
|
|
545
|
+
function createAuthProviderIntegration(config) {
|
|
546
|
+
var _a;
|
|
547
|
+
return Object.freeze({
|
|
548
|
+
...config,
|
|
549
|
+
resolvers: Object.freeze((_a = config.resolvers) != null ? _a : {})
|
|
550
|
+
});
|
|
628
551
|
}
|
|
629
552
|
|
|
630
553
|
const atlassianDefaultAuthHandler = async ({
|
|
@@ -635,9 +558,7 @@ const atlassianDefaultAuthHandler = async ({
|
|
|
635
558
|
});
|
|
636
559
|
class AtlassianAuthProvider {
|
|
637
560
|
constructor(options) {
|
|
638
|
-
this.
|
|
639
|
-
this.logger = options.logger;
|
|
640
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
561
|
+
this.resolverContext = options.resolverContext;
|
|
641
562
|
this.authHandler = options.authHandler;
|
|
642
563
|
this.signInResolver = options.signInResolver;
|
|
643
564
|
this._strategy = new AtlassianStrategy({
|
|
@@ -667,12 +588,7 @@ class AtlassianAuthProvider {
|
|
|
667
588
|
};
|
|
668
589
|
}
|
|
669
590
|
async handleResult(result) {
|
|
670
|
-
const
|
|
671
|
-
logger: this.logger,
|
|
672
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
673
|
-
tokenIssuer: this.tokenIssuer
|
|
674
|
-
};
|
|
675
|
-
const { profile } = await this.authHandler(result, context);
|
|
591
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
676
592
|
const response = {
|
|
677
593
|
providerInfo: {
|
|
678
594
|
idToken: result.params.id_token,
|
|
@@ -686,7 +602,7 @@ class AtlassianAuthProvider {
|
|
|
686
602
|
response.backstageIdentity = await this.signInResolver({
|
|
687
603
|
result,
|
|
688
604
|
profile
|
|
689
|
-
},
|
|
605
|
+
}, this.resolverContext);
|
|
690
606
|
}
|
|
691
607
|
return response;
|
|
692
608
|
}
|
|
@@ -703,45 +619,33 @@ class AtlassianAuthProvider {
|
|
|
703
619
|
};
|
|
704
620
|
}
|
|
705
621
|
}
|
|
706
|
-
const
|
|
707
|
-
|
|
708
|
-
providerId,
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
clientSecret,
|
|
730
|
-
scopes,
|
|
731
|
-
callbackUrl,
|
|
732
|
-
authHandler,
|
|
733
|
-
signInResolver: (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver,
|
|
734
|
-
catalogIdentityClient,
|
|
735
|
-
logger,
|
|
736
|
-
tokenIssuer
|
|
737
|
-
});
|
|
738
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
739
|
-
providerId,
|
|
740
|
-
tokenIssuer,
|
|
741
|
-
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
|
+
});
|
|
742
645
|
});
|
|
743
|
-
}
|
|
744
|
-
};
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
const createAtlassianProvider = atlassian.create;
|
|
745
649
|
|
|
746
650
|
class Auth0Strategy extends OAuth2Strategy__default["default"] {
|
|
747
651
|
constructor(options, verify) {
|
|
@@ -760,9 +664,7 @@ class Auth0AuthProvider {
|
|
|
760
664
|
constructor(options) {
|
|
761
665
|
this.signInResolver = options.signInResolver;
|
|
762
666
|
this.authHandler = options.authHandler;
|
|
763
|
-
this.
|
|
764
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
765
|
-
this.logger = options.logger;
|
|
667
|
+
this.resolverContext = options.resolverContext;
|
|
766
668
|
this._strategy = new Auth0Strategy({
|
|
767
669
|
clientID: options.clientId,
|
|
768
670
|
clientSecret: options.clientSecret,
|
|
@@ -808,12 +710,7 @@ class Auth0AuthProvider {
|
|
|
808
710
|
};
|
|
809
711
|
}
|
|
810
712
|
async handleResult(result) {
|
|
811
|
-
const
|
|
812
|
-
logger: this.logger,
|
|
813
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
814
|
-
tokenIssuer: this.tokenIssuer
|
|
815
|
-
};
|
|
816
|
-
const { profile } = await this.authHandler(result, context);
|
|
713
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
817
714
|
const response = {
|
|
818
715
|
providerInfo: {
|
|
819
716
|
idToken: result.params.id_token,
|
|
@@ -827,62 +724,42 @@ class Auth0AuthProvider {
|
|
|
827
724
|
response.backstageIdentity = await this.signInResolver({
|
|
828
725
|
result,
|
|
829
726
|
profile
|
|
830
|
-
},
|
|
727
|
+
}, this.resolverContext);
|
|
831
728
|
}
|
|
832
729
|
return response;
|
|
833
730
|
}
|
|
834
731
|
}
|
|
835
|
-
const
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
const
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
});
|
|
863
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
864
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
865
|
-
});
|
|
866
|
-
const signInResolver = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : defaultSignInResolver$1;
|
|
867
|
-
const provider = new Auth0AuthProvider({
|
|
868
|
-
clientId,
|
|
869
|
-
clientSecret,
|
|
870
|
-
callbackUrl,
|
|
871
|
-
domain,
|
|
872
|
-
authHandler,
|
|
873
|
-
signInResolver,
|
|
874
|
-
tokenIssuer,
|
|
875
|
-
catalogIdentityClient,
|
|
876
|
-
logger
|
|
877
|
-
});
|
|
878
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
879
|
-
disableRefresh: true,
|
|
880
|
-
providerId,
|
|
881
|
-
tokenIssuer,
|
|
882
|
-
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
|
+
});
|
|
883
759
|
});
|
|
884
|
-
}
|
|
885
|
-
};
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
const createAuth0Provider = auth0.create;
|
|
886
763
|
|
|
887
764
|
const ALB_JWT_HEADER = "x-amzn-oidc-data";
|
|
888
765
|
const ALB_ACCESS_TOKEN_HEADER = "x-amzn-oidc-accesstoken";
|
|
@@ -896,9 +773,7 @@ class AwsAlbAuthProvider {
|
|
|
896
773
|
this.issuer = options.issuer;
|
|
897
774
|
this.authHandler = options.authHandler;
|
|
898
775
|
this.signInResolver = options.signInResolver;
|
|
899
|
-
this.
|
|
900
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
901
|
-
this.logger = options.logger;
|
|
776
|
+
this.resolverContext = options.resolverContext;
|
|
902
777
|
this.keyCache = new NodeCache__default["default"]({ stdTTL: 3600 });
|
|
903
778
|
}
|
|
904
779
|
frameHandler() {
|
|
@@ -910,9 +785,7 @@ class AwsAlbAuthProvider {
|
|
|
910
785
|
const response = await this.handleResult(result);
|
|
911
786
|
res.json(response);
|
|
912
787
|
} catch (e) {
|
|
913
|
-
|
|
914
|
-
res.status(401);
|
|
915
|
-
res.end();
|
|
788
|
+
throw new errors.AuthenticationError("Exception occurred during AWS ALB token refresh", e);
|
|
916
789
|
}
|
|
917
790
|
}
|
|
918
791
|
start() {
|
|
@@ -956,16 +829,11 @@ class AwsAlbAuthProvider {
|
|
|
956
829
|
}
|
|
957
830
|
}
|
|
958
831
|
async handleResult(result) {
|
|
959
|
-
const
|
|
960
|
-
tokenIssuer: this.tokenIssuer,
|
|
961
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
962
|
-
logger: this.logger
|
|
963
|
-
};
|
|
964
|
-
const { profile } = await this.authHandler(result, context);
|
|
832
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
965
833
|
const backstageIdentity = await this.signInResolver({
|
|
966
834
|
result,
|
|
967
835
|
profile
|
|
968
|
-
},
|
|
836
|
+
}, this.resolverContext);
|
|
969
837
|
return {
|
|
970
838
|
providerInfo: {
|
|
971
839
|
accessToken: result.accessToken,
|
|
@@ -980,46 +848,40 @@ class AwsAlbAuthProvider {
|
|
|
980
848
|
if (optionalCacheKey) {
|
|
981
849
|
return crypto__namespace.createPublicKey(optionalCacheKey);
|
|
982
850
|
}
|
|
983
|
-
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());
|
|
984
852
|
const keyValue = crypto__namespace.createPublicKey(keyText);
|
|
985
853
|
this.keyCache.set(keyId, keyValue.export({ format: "pem", type: "spki" }));
|
|
986
854
|
return keyValue;
|
|
987
855
|
}
|
|
988
856
|
}
|
|
989
|
-
const
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
logger
|
|
1012
|
-
});
|
|
1013
|
-
};
|
|
1014
|
-
};
|
|
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;
|
|
1015
879
|
|
|
1016
880
|
class BitbucketAuthProvider {
|
|
1017
881
|
constructor(options) {
|
|
1018
882
|
this.signInResolver = options.signInResolver;
|
|
1019
883
|
this.authHandler = options.authHandler;
|
|
1020
|
-
this.
|
|
1021
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1022
|
-
this.logger = options.logger;
|
|
884
|
+
this.resolverContext = options.resolverContext;
|
|
1023
885
|
this._strategy = new passportBitbucketOauth2.Strategy({
|
|
1024
886
|
clientID: options.clientId,
|
|
1025
887
|
clientSecret: options.clientSecret,
|
|
@@ -1065,12 +927,7 @@ class BitbucketAuthProvider {
|
|
|
1065
927
|
}
|
|
1066
928
|
async handleResult(result) {
|
|
1067
929
|
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
1068
|
-
const
|
|
1069
|
-
logger: this.logger,
|
|
1070
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1071
|
-
tokenIssuer: this.tokenIssuer
|
|
1072
|
-
};
|
|
1073
|
-
const { profile } = await this.authHandler(result, context);
|
|
930
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1074
931
|
const response = {
|
|
1075
932
|
providerInfo: {
|
|
1076
933
|
idToken: result.params.id_token,
|
|
@@ -1084,79 +941,69 @@ class BitbucketAuthProvider {
|
|
|
1084
941
|
response.backstageIdentity = await this.signInResolver({
|
|
1085
942
|
result,
|
|
1086
943
|
profile
|
|
1087
|
-
},
|
|
944
|
+
}, this.resolverContext);
|
|
1088
945
|
}
|
|
1089
946
|
return response;
|
|
1090
947
|
}
|
|
1091
948
|
}
|
|
1092
|
-
const
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
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
|
+
};
|
|
1100
1001
|
}
|
|
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 bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
1107
|
-
const { result } = info;
|
|
1108
|
-
if (!result.fullProfile.id) {
|
|
1109
|
-
throw new Error("Bitbucket profile contained no User ID");
|
|
1110
1002
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
});
|
|
1116
|
-
const claims = getEntityClaims(entity);
|
|
1117
|
-
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1118
|
-
return { id: entity.metadata.name, entity, token };
|
|
1119
|
-
};
|
|
1120
|
-
const createBitbucketProvider = (options) => {
|
|
1121
|
-
return ({
|
|
1122
|
-
providerId,
|
|
1123
|
-
globalConfig,
|
|
1124
|
-
config,
|
|
1125
|
-
tokenIssuer,
|
|
1126
|
-
tokenManager,
|
|
1127
|
-
catalogApi,
|
|
1128
|
-
logger
|
|
1129
|
-
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1130
|
-
var _a;
|
|
1131
|
-
const clientId = envConfig.getString("clientId");
|
|
1132
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
1133
|
-
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1134
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1135
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1136
|
-
catalogApi,
|
|
1137
|
-
tokenManager
|
|
1138
|
-
});
|
|
1139
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1140
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1141
|
-
});
|
|
1142
|
-
const provider = new BitbucketAuthProvider({
|
|
1143
|
-
clientId,
|
|
1144
|
-
clientSecret,
|
|
1145
|
-
callbackUrl,
|
|
1146
|
-
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
1147
|
-
authHandler,
|
|
1148
|
-
tokenIssuer,
|
|
1149
|
-
catalogIdentityClient,
|
|
1150
|
-
logger
|
|
1151
|
-
});
|
|
1152
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1153
|
-
disableRefresh: false,
|
|
1154
|
-
providerId,
|
|
1155
|
-
tokenIssuer,
|
|
1156
|
-
callbackUrl
|
|
1157
|
-
});
|
|
1158
|
-
});
|
|
1159
|
-
};
|
|
1003
|
+
});
|
|
1004
|
+
const createBitbucketProvider = bitbucket.create;
|
|
1005
|
+
const bitbucketUsernameSignInResolver = bitbucket.resolvers.usernameMatchingUserEntityAnnotation();
|
|
1006
|
+
const bitbucketUserIdSignInResolver = bitbucket.resolvers.userIdMatchingUserEntityAnnotation();
|
|
1160
1007
|
|
|
1161
1008
|
const ACCESS_TOKEN_PREFIX = "access-token.";
|
|
1162
1009
|
const BACKSTAGE_SESSION_EXPIRATION = 3600;
|
|
@@ -1165,9 +1012,7 @@ class GithubAuthProvider {
|
|
|
1165
1012
|
this.signInResolver = options.signInResolver;
|
|
1166
1013
|
this.authHandler = options.authHandler;
|
|
1167
1014
|
this.stateEncoder = options.stateEncoder;
|
|
1168
|
-
this.
|
|
1169
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1170
|
-
this.logger = options.logger;
|
|
1015
|
+
this.resolverContext = options.resolverContext;
|
|
1171
1016
|
this._strategy = new passportGithub2.Strategy({
|
|
1172
1017
|
clientID: options.clientId,
|
|
1173
1018
|
clientSecret: options.clientSecret,
|
|
@@ -1227,12 +1072,7 @@ class GithubAuthProvider {
|
|
|
1227
1072
|
};
|
|
1228
1073
|
}
|
|
1229
1074
|
async handleResult(result) {
|
|
1230
|
-
const
|
|
1231
|
-
logger: this.logger,
|
|
1232
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1233
|
-
tokenIssuer: this.tokenIssuer
|
|
1234
|
-
};
|
|
1235
|
-
const { profile } = await this.authHandler(result, context);
|
|
1075
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1236
1076
|
const expiresInStr = result.params.expires_in;
|
|
1237
1077
|
let expiresInSeconds = expiresInStr === void 0 ? void 0 : Number(expiresInStr);
|
|
1238
1078
|
let backstageIdentity = void 0;
|
|
@@ -1240,7 +1080,7 @@ class GithubAuthProvider {
|
|
|
1240
1080
|
backstageIdentity = await this.signInResolver({
|
|
1241
1081
|
result,
|
|
1242
1082
|
profile
|
|
1243
|
-
},
|
|
1083
|
+
}, this.resolverContext);
|
|
1244
1084
|
if (expiresInSeconds) {
|
|
1245
1085
|
expiresInSeconds = Math.min(expiresInSeconds, BACKSTAGE_SESSION_EXPIRATION);
|
|
1246
1086
|
} else {
|
|
@@ -1258,99 +1098,58 @@ class GithubAuthProvider {
|
|
|
1258
1098
|
};
|
|
1259
1099
|
}
|
|
1260
1100
|
}
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1297
|
-
catalogApi,
|
|
1298
|
-
tokenManager
|
|
1299
|
-
});
|
|
1300
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
1301
|
-
profile: makeProfileInfo(fullProfile)
|
|
1302
|
-
});
|
|
1303
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : githubDefaultSignInResolver;
|
|
1304
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1305
|
-
catalogIdentityClient,
|
|
1306
|
-
tokenIssuer,
|
|
1307
|
-
logger
|
|
1308
|
-
});
|
|
1309
|
-
const stateEncoder = (_c = options == null ? void 0 : options.stateEncoder) != null ? _c : async (req) => {
|
|
1310
|
-
return { encodedState: encodeState(req.state) };
|
|
1311
|
-
};
|
|
1312
|
-
const provider = new GithubAuthProvider({
|
|
1313
|
-
clientId,
|
|
1314
|
-
clientSecret,
|
|
1315
|
-
callbackUrl,
|
|
1316
|
-
tokenUrl,
|
|
1317
|
-
userProfileUrl,
|
|
1318
|
-
authorizationUrl,
|
|
1319
|
-
signInResolver,
|
|
1320
|
-
authHandler,
|
|
1321
|
-
tokenIssuer,
|
|
1322
|
-
catalogIdentityClient,
|
|
1323
|
-
stateEncoder,
|
|
1324
|
-
logger
|
|
1325
|
-
});
|
|
1326
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1327
|
-
persistScopes: true,
|
|
1328
|
-
providerId,
|
|
1329
|
-
tokenIssuer,
|
|
1330
|
-
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
|
+
});
|
|
1331
1136
|
});
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
namespace: catalogModel.DEFAULT_NAMESPACE,
|
|
1344
|
-
name: id
|
|
1345
|
-
});
|
|
1346
|
-
const token = await ctx.tokenIssuer.issueToken({
|
|
1347
|
-
claims: {
|
|
1348
|
-
sub: entityRef,
|
|
1349
|
-
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
|
+
};
|
|
1350
1148
|
}
|
|
1351
|
-
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
const createGithubProvider = github.create;
|
|
1152
|
+
|
|
1354
1153
|
const gitlabDefaultAuthHandler = async ({
|
|
1355
1154
|
fullProfile,
|
|
1356
1155
|
params
|
|
@@ -1359,9 +1158,7 @@ const gitlabDefaultAuthHandler = async ({
|
|
|
1359
1158
|
});
|
|
1360
1159
|
class GitlabAuthProvider {
|
|
1361
1160
|
constructor(options) {
|
|
1362
|
-
this.
|
|
1363
|
-
this.logger = options.logger;
|
|
1364
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
1161
|
+
this.resolverContext = options.resolverContext;
|
|
1365
1162
|
this.authHandler = options.authHandler;
|
|
1366
1163
|
this.signInResolver = options.signInResolver;
|
|
1367
1164
|
this._strategy = new passportGitlab2.Strategy({
|
|
@@ -1401,12 +1198,7 @@ class GitlabAuthProvider {
|
|
|
1401
1198
|
};
|
|
1402
1199
|
}
|
|
1403
1200
|
async handleResult(result) {
|
|
1404
|
-
const
|
|
1405
|
-
logger: this.logger,
|
|
1406
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1407
|
-
tokenIssuer: this.tokenIssuer
|
|
1408
|
-
};
|
|
1409
|
-
const { profile } = await this.authHandler(result, context);
|
|
1201
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1410
1202
|
const response = {
|
|
1411
1203
|
providerInfo: {
|
|
1412
1204
|
idToken: result.params.id_token,
|
|
@@ -1420,67 +1212,58 @@ class GitlabAuthProvider {
|
|
|
1420
1212
|
response.backstageIdentity = await this.signInResolver({
|
|
1421
1213
|
result,
|
|
1422
1214
|
profile
|
|
1423
|
-
},
|
|
1215
|
+
}, this.resolverContext);
|
|
1424
1216
|
}
|
|
1425
1217
|
return response;
|
|
1426
1218
|
}
|
|
1427
1219
|
}
|
|
1428
|
-
const
|
|
1429
|
-
|
|
1430
|
-
providerId,
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
tokenIssuer,
|
|
1454
|
-
logger
|
|
1455
|
-
});
|
|
1456
|
-
const provider = new GitlabAuthProvider({
|
|
1457
|
-
clientId,
|
|
1458
|
-
clientSecret,
|
|
1459
|
-
callbackUrl,
|
|
1460
|
-
baseUrl,
|
|
1461
|
-
authHandler,
|
|
1462
|
-
signInResolver,
|
|
1463
|
-
catalogIdentityClient,
|
|
1464
|
-
logger,
|
|
1465
|
-
tokenIssuer
|
|
1466
|
-
});
|
|
1467
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1468
|
-
disableRefresh: false,
|
|
1469
|
-
providerId,
|
|
1470
|
-
tokenIssuer,
|
|
1471
|
-
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
|
+
});
|
|
1472
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 }
|
|
1473
1258
|
});
|
|
1474
1259
|
};
|
|
1475
1260
|
|
|
1476
1261
|
class GoogleAuthProvider {
|
|
1477
1262
|
constructor(options) {
|
|
1478
|
-
this.signInResolver = options.signInResolver;
|
|
1479
1263
|
this.authHandler = options.authHandler;
|
|
1480
|
-
this.
|
|
1481
|
-
this.
|
|
1482
|
-
this.
|
|
1483
|
-
this._strategy = new passportGoogleOauth20.Strategy({
|
|
1264
|
+
this.signInResolver = options.signInResolver;
|
|
1265
|
+
this.resolverContext = options.resolverContext;
|
|
1266
|
+
this.strategy = new passportGoogleOauth20.Strategy({
|
|
1484
1267
|
clientID: options.clientId,
|
|
1485
1268
|
clientSecret: options.clientSecret,
|
|
1486
1269
|
callbackURL: options.callbackUrl,
|
|
@@ -1497,7 +1280,7 @@ class GoogleAuthProvider {
|
|
|
1497
1280
|
});
|
|
1498
1281
|
}
|
|
1499
1282
|
async start(req) {
|
|
1500
|
-
return await executeRedirectStrategy(req, this.
|
|
1283
|
+
return await executeRedirectStrategy(req, this.strategy, {
|
|
1501
1284
|
accessType: "offline",
|
|
1502
1285
|
prompt: "consent",
|
|
1503
1286
|
scope: req.scope,
|
|
@@ -1505,15 +1288,15 @@ class GoogleAuthProvider {
|
|
|
1505
1288
|
});
|
|
1506
1289
|
}
|
|
1507
1290
|
async handler(req) {
|
|
1508
|
-
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.
|
|
1291
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
1509
1292
|
return {
|
|
1510
1293
|
response: await this.handleResult(result),
|
|
1511
1294
|
refreshToken: privateInfo.refreshToken
|
|
1512
1295
|
};
|
|
1513
1296
|
}
|
|
1514
1297
|
async refresh(req) {
|
|
1515
|
-
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(this.
|
|
1516
|
-
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);
|
|
1517
1300
|
return {
|
|
1518
1301
|
response: await this.handleResult({
|
|
1519
1302
|
fullProfile,
|
|
@@ -1524,12 +1307,7 @@ class GoogleAuthProvider {
|
|
|
1524
1307
|
};
|
|
1525
1308
|
}
|
|
1526
1309
|
async handleResult(result) {
|
|
1527
|
-
const
|
|
1528
|
-
logger: this.logger,
|
|
1529
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1530
|
-
tokenIssuer: this.tokenIssuer
|
|
1531
|
-
};
|
|
1532
|
-
const { profile } = await this.authHandler(result, context);
|
|
1310
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1533
1311
|
const response = {
|
|
1534
1312
|
providerInfo: {
|
|
1535
1313
|
idToken: result.params.id_token,
|
|
@@ -1543,109 +1321,63 @@ class GoogleAuthProvider {
|
|
|
1543
1321
|
response.backstageIdentity = await this.signInResolver({
|
|
1544
1322
|
result,
|
|
1545
1323
|
profile
|
|
1546
|
-
},
|
|
1324
|
+
}, this.resolverContext);
|
|
1547
1325
|
}
|
|
1548
1326
|
return response;
|
|
1549
1327
|
}
|
|
1550
1328
|
}
|
|
1551
|
-
const
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
}
|
|
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
|
+
});
|
|
1576
1353
|
});
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
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
|
+
};
|
|
1591
1369
|
}
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
const
|
|
1596
|
-
return ({
|
|
1597
|
-
providerId,
|
|
1598
|
-
globalConfig,
|
|
1599
|
-
config,
|
|
1600
|
-
tokenIssuer,
|
|
1601
|
-
tokenManager,
|
|
1602
|
-
catalogApi,
|
|
1603
|
-
logger
|
|
1604
|
-
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1605
|
-
var _a, _b;
|
|
1606
|
-
const clientId = envConfig.getString("clientId");
|
|
1607
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
1608
|
-
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1609
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1610
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1611
|
-
catalogApi,
|
|
1612
|
-
tokenManager
|
|
1613
|
-
});
|
|
1614
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1615
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1616
|
-
});
|
|
1617
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : googleDefaultSignInResolver;
|
|
1618
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1619
|
-
catalogIdentityClient,
|
|
1620
|
-
tokenIssuer,
|
|
1621
|
-
logger
|
|
1622
|
-
});
|
|
1623
|
-
const provider = new GoogleAuthProvider({
|
|
1624
|
-
clientId,
|
|
1625
|
-
clientSecret,
|
|
1626
|
-
callbackUrl,
|
|
1627
|
-
signInResolver,
|
|
1628
|
-
authHandler,
|
|
1629
|
-
tokenIssuer,
|
|
1630
|
-
catalogIdentityClient,
|
|
1631
|
-
logger
|
|
1632
|
-
});
|
|
1633
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1634
|
-
disableRefresh: false,
|
|
1635
|
-
providerId,
|
|
1636
|
-
tokenIssuer,
|
|
1637
|
-
callbackUrl
|
|
1638
|
-
});
|
|
1639
|
-
});
|
|
1640
|
-
};
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1372
|
+
const createGoogleProvider = google.create;
|
|
1373
|
+
const googleEmailSignInResolver = google.resolvers.emailMatchingUserEntityAnnotation();
|
|
1641
1374
|
|
|
1642
1375
|
class MicrosoftAuthProvider {
|
|
1643
1376
|
constructor(options) {
|
|
1644
1377
|
this.signInResolver = options.signInResolver;
|
|
1645
1378
|
this.authHandler = options.authHandler;
|
|
1646
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
1647
1379
|
this.logger = options.logger;
|
|
1648
|
-
this.
|
|
1380
|
+
this.resolverContext = options.resolverContext;
|
|
1649
1381
|
this._strategy = new passportMicrosoft.Strategy({
|
|
1650
1382
|
clientID: options.clientId,
|
|
1651
1383
|
clientSecret: options.clientSecret,
|
|
@@ -1685,12 +1417,7 @@ class MicrosoftAuthProvider {
|
|
|
1685
1417
|
async handleResult(result) {
|
|
1686
1418
|
const photo = await this.getUserPhoto(result.accessToken);
|
|
1687
1419
|
result.fullProfile.photos = photo ? [{ value: photo }] : void 0;
|
|
1688
|
-
const
|
|
1689
|
-
logger: this.logger,
|
|
1690
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1691
|
-
tokenIssuer: this.tokenIssuer
|
|
1692
|
-
};
|
|
1693
|
-
const { profile } = await this.authHandler(result, context);
|
|
1420
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1694
1421
|
const response = {
|
|
1695
1422
|
providerInfo: {
|
|
1696
1423
|
idToken: result.params.id_token,
|
|
@@ -1704,118 +1431,81 @@ class MicrosoftAuthProvider {
|
|
|
1704
1431
|
response.backstageIdentity = await this.signInResolver({
|
|
1705
1432
|
result,
|
|
1706
1433
|
profile
|
|
1707
|
-
},
|
|
1434
|
+
}, this.resolverContext);
|
|
1708
1435
|
}
|
|
1709
1436
|
return response;
|
|
1710
1437
|
}
|
|
1711
|
-
getUserPhoto(accessToken) {
|
|
1712
|
-
|
|
1713
|
-
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", {
|
|
1714
1441
|
headers: {
|
|
1715
1442
|
Authorization: `Bearer ${accessToken}`
|
|
1716
1443
|
}
|
|
1717
|
-
}).then((response) => response.arrayBuffer()).then((arrayBuffer) => {
|
|
1718
|
-
const imageUrl = `data:image/jpeg;base64,${Buffer.from(arrayBuffer).toString("base64")}`;
|
|
1719
|
-
resolve(imageUrl);
|
|
1720
|
-
}).catch((error) => {
|
|
1721
|
-
this.logger.warn(`Could not retrieve user profile photo from Microsoft Graph API: ${error}`);
|
|
1722
|
-
resolve(void 0);
|
|
1723
1444
|
});
|
|
1724
|
-
|
|
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;
|
|
1450
|
+
}
|
|
1725
1451
|
}
|
|
1726
1452
|
}
|
|
1727
|
-
const
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
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
|
+
});
|
|
1483
|
+
});
|
|
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
|
+
};
|
|
1735
1498
|
}
|
|
1736
|
-
});
|
|
1737
|
-
const claims = getEntityClaims(entity);
|
|
1738
|
-
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1739
|
-
return { id: entity.metadata.name, entity, token };
|
|
1740
|
-
};
|
|
1741
|
-
const microsoftDefaultSignInResolver = async (info, ctx) => {
|
|
1742
|
-
const { profile } = info;
|
|
1743
|
-
if (!profile.email) {
|
|
1744
|
-
throw new Error("Profile contained no email");
|
|
1745
1499
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
namespace: catalogModel.DEFAULT_NAMESPACE,
|
|
1750
|
-
name: userId
|
|
1751
|
-
});
|
|
1752
|
-
const token = await ctx.tokenIssuer.issueToken({
|
|
1753
|
-
claims: {
|
|
1754
|
-
sub: entityRef,
|
|
1755
|
-
ent: [entityRef]
|
|
1756
|
-
}
|
|
1757
|
-
});
|
|
1758
|
-
return { id: userId, token };
|
|
1759
|
-
};
|
|
1760
|
-
const createMicrosoftProvider = (options) => {
|
|
1761
|
-
return ({
|
|
1762
|
-
providerId,
|
|
1763
|
-
globalConfig,
|
|
1764
|
-
config,
|
|
1765
|
-
tokenIssuer,
|
|
1766
|
-
tokenManager,
|
|
1767
|
-
catalogApi,
|
|
1768
|
-
logger
|
|
1769
|
-
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1770
|
-
var _a, _b;
|
|
1771
|
-
const clientId = envConfig.getString("clientId");
|
|
1772
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
1773
|
-
const tenantId = envConfig.getString("tenantId");
|
|
1774
|
-
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1775
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1776
|
-
const authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;
|
|
1777
|
-
const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
|
|
1778
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1779
|
-
catalogApi,
|
|
1780
|
-
tokenManager
|
|
1781
|
-
});
|
|
1782
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1783
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1784
|
-
});
|
|
1785
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : microsoftDefaultSignInResolver;
|
|
1786
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1787
|
-
catalogIdentityClient,
|
|
1788
|
-
tokenIssuer,
|
|
1789
|
-
logger
|
|
1790
|
-
});
|
|
1791
|
-
const provider = new MicrosoftAuthProvider({
|
|
1792
|
-
clientId,
|
|
1793
|
-
clientSecret,
|
|
1794
|
-
callbackUrl,
|
|
1795
|
-
authorizationUrl,
|
|
1796
|
-
tokenUrl,
|
|
1797
|
-
authHandler,
|
|
1798
|
-
signInResolver,
|
|
1799
|
-
catalogIdentityClient,
|
|
1800
|
-
logger,
|
|
1801
|
-
tokenIssuer
|
|
1802
|
-
});
|
|
1803
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1804
|
-
disableRefresh: false,
|
|
1805
|
-
providerId,
|
|
1806
|
-
tokenIssuer,
|
|
1807
|
-
callbackUrl
|
|
1808
|
-
});
|
|
1809
|
-
});
|
|
1810
|
-
};
|
|
1500
|
+
});
|
|
1501
|
+
const createMicrosoftProvider = microsoft.create;
|
|
1502
|
+
const microsoftEmailSignInResolver = microsoft.resolvers.emailMatchingUserEntityAnnotation();
|
|
1811
1503
|
|
|
1812
1504
|
class OAuth2AuthProvider {
|
|
1813
1505
|
constructor(options) {
|
|
1814
1506
|
this.signInResolver = options.signInResolver;
|
|
1815
1507
|
this.authHandler = options.authHandler;
|
|
1816
|
-
this.
|
|
1817
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1818
|
-
this.logger = options.logger;
|
|
1508
|
+
this.resolverContext = options.resolverContext;
|
|
1819
1509
|
this._strategy = new OAuth2Strategy.Strategy({
|
|
1820
1510
|
clientID: options.clientId,
|
|
1821
1511
|
clientSecret: options.clientSecret,
|
|
@@ -1867,12 +1557,7 @@ class OAuth2AuthProvider {
|
|
|
1867
1557
|
};
|
|
1868
1558
|
}
|
|
1869
1559
|
async handleResult(result) {
|
|
1870
|
-
const
|
|
1871
|
-
logger: this.logger,
|
|
1872
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
1873
|
-
tokenIssuer: this.tokenIssuer
|
|
1874
|
-
};
|
|
1875
|
-
const { profile } = await this.authHandler(result, context);
|
|
1560
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1876
1561
|
const response = {
|
|
1877
1562
|
providerInfo: {
|
|
1878
1563
|
idToken: result.params.id_token,
|
|
@@ -1886,7 +1571,7 @@ class OAuth2AuthProvider {
|
|
|
1886
1571
|
response.backstageIdentity = await this.signInResolver({
|
|
1887
1572
|
result,
|
|
1888
1573
|
profile
|
|
1889
|
-
},
|
|
1574
|
+
}, this.resolverContext);
|
|
1890
1575
|
}
|
|
1891
1576
|
return response;
|
|
1892
1577
|
}
|
|
@@ -1894,87 +1579,48 @@ class OAuth2AuthProvider {
|
|
|
1894
1579
|
return Buffer.from(`${clientID}:${clientSecret}`).toString("base64");
|
|
1895
1580
|
}
|
|
1896
1581
|
}
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1931
|
-
const authorizationUrl = envConfig.getString("authorizationUrl");
|
|
1932
|
-
const tokenUrl = envConfig.getString("tokenUrl");
|
|
1933
|
-
const scope = envConfig.getOptionalString("scope");
|
|
1934
|
-
const includeBasicAuth = envConfig.getOptionalBoolean("includeBasicAuth");
|
|
1935
|
-
const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
|
|
1936
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1937
|
-
catalogApi,
|
|
1938
|
-
tokenManager
|
|
1939
|
-
});
|
|
1940
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1941
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1942
|
-
});
|
|
1943
|
-
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver;
|
|
1944
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
1945
|
-
catalogIdentityClient,
|
|
1946
|
-
tokenIssuer,
|
|
1947
|
-
logger
|
|
1948
|
-
});
|
|
1949
|
-
const provider = new OAuth2AuthProvider({
|
|
1950
|
-
clientId,
|
|
1951
|
-
clientSecret,
|
|
1952
|
-
tokenIssuer,
|
|
1953
|
-
catalogIdentityClient,
|
|
1954
|
-
callbackUrl,
|
|
1955
|
-
signInResolver,
|
|
1956
|
-
authHandler,
|
|
1957
|
-
authorizationUrl,
|
|
1958
|
-
tokenUrl,
|
|
1959
|
-
scope,
|
|
1960
|
-
logger,
|
|
1961
|
-
includeBasicAuth
|
|
1962
|
-
});
|
|
1963
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1964
|
-
disableRefresh,
|
|
1965
|
-
providerId,
|
|
1966
|
-
tokenIssuer,
|
|
1967
|
-
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
|
+
});
|
|
1968
1615
|
});
|
|
1969
|
-
}
|
|
1970
|
-
};
|
|
1616
|
+
}
|
|
1617
|
+
});
|
|
1618
|
+
const createOAuth2Provider = oauth2.create;
|
|
1971
1619
|
|
|
1972
1620
|
const OAUTH2_PROXY_JWT_HEADER = "X-OAUTH2-PROXY-ID-TOKEN";
|
|
1973
1621
|
class Oauth2ProxyAuthProvider {
|
|
1974
1622
|
constructor(options) {
|
|
1975
|
-
this.
|
|
1976
|
-
this.logger = options.logger;
|
|
1977
|
-
this.tokenIssuer = options.tokenIssuer;
|
|
1623
|
+
this.resolverContext = options.resolverContext;
|
|
1978
1624
|
this.signInResolver = options.signInResolver;
|
|
1979
1625
|
this.authHandler = options.authHandler;
|
|
1980
1626
|
}
|
|
@@ -1987,25 +1633,18 @@ class Oauth2ProxyAuthProvider {
|
|
|
1987
1633
|
const response = await this.handleResult(result);
|
|
1988
1634
|
res.json(response);
|
|
1989
1635
|
} catch (e) {
|
|
1990
|
-
|
|
1991
|
-
res.status(401);
|
|
1992
|
-
res.end();
|
|
1636
|
+
throw new errors.AuthenticationError("Refresh failed", e);
|
|
1993
1637
|
}
|
|
1994
1638
|
}
|
|
1995
1639
|
start() {
|
|
1996
1640
|
return Promise.resolve(void 0);
|
|
1997
1641
|
}
|
|
1998
1642
|
async handleResult(result) {
|
|
1999
|
-
const
|
|
2000
|
-
logger: this.logger,
|
|
2001
|
-
tokenIssuer: this.tokenIssuer,
|
|
2002
|
-
catalogIdentityClient: this.catalogIdentityClient
|
|
2003
|
-
};
|
|
2004
|
-
const { profile } = await this.authHandler(result, ctx);
|
|
1643
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2005
1644
|
const backstageSignInResult = await this.signInResolver({
|
|
2006
1645
|
result,
|
|
2007
1646
|
profile
|
|
2008
|
-
},
|
|
1647
|
+
}, this.resolverContext);
|
|
2009
1648
|
return {
|
|
2010
1649
|
providerInfo: {
|
|
2011
1650
|
accessToken: result.accessToken
|
|
@@ -2027,21 +1666,20 @@ class Oauth2ProxyAuthProvider {
|
|
|
2027
1666
|
};
|
|
2028
1667
|
}
|
|
2029
1668
|
}
|
|
2030
|
-
const
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
};
|
|
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;
|
|
2045
1683
|
|
|
2046
1684
|
class OidcAuthProvider {
|
|
2047
1685
|
constructor(options) {
|
|
@@ -2050,9 +1688,7 @@ class OidcAuthProvider {
|
|
|
2050
1688
|
this.prompt = options.prompt;
|
|
2051
1689
|
this.signInResolver = options.signInResolver;
|
|
2052
1690
|
this.authHandler = options.authHandler;
|
|
2053
|
-
this.
|
|
2054
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2055
|
-
this.logger = options.logger;
|
|
1691
|
+
this.resolverContext = options.resolverContext;
|
|
2056
1692
|
}
|
|
2057
1693
|
async start(req) {
|
|
2058
1694
|
const { strategy } = await this.implementation;
|
|
@@ -2112,12 +1748,7 @@ class OidcAuthProvider {
|
|
|
2112
1748
|
return { strategy, client };
|
|
2113
1749
|
}
|
|
2114
1750
|
async handleResult(result) {
|
|
2115
|
-
const
|
|
2116
|
-
logger: this.logger,
|
|
2117
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2118
|
-
tokenIssuer: this.tokenIssuer
|
|
2119
|
-
};
|
|
2120
|
-
const { profile } = await this.authHandler(result, context);
|
|
1751
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2121
1752
|
const response = {
|
|
2122
1753
|
providerInfo: {
|
|
2123
1754
|
idToken: result.tokenset.id_token,
|
|
@@ -2131,92 +1762,55 @@ class OidcAuthProvider {
|
|
|
2131
1762
|
response.backstageIdentity = await this.signInResolver({
|
|
2132
1763
|
result,
|
|
2133
1764
|
profile
|
|
2134
|
-
},
|
|
1765
|
+
}, this.resolverContext);
|
|
2135
1766
|
}
|
|
2136
1767
|
return response;
|
|
2137
1768
|
}
|
|
2138
1769
|
}
|
|
2139
|
-
const
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
};
|
|
2158
|
-
const
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
const scope = envConfig.getOptionalString("scope");
|
|
2176
|
-
const prompt = envConfig.getOptionalString("prompt");
|
|
2177
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2178
|
-
catalogApi,
|
|
2179
|
-
tokenManager
|
|
2180
|
-
});
|
|
2181
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
|
|
2182
|
-
profile: {
|
|
2183
|
-
displayName: userinfo.name,
|
|
2184
|
-
email: userinfo.email,
|
|
2185
|
-
picture: userinfo.picture
|
|
2186
|
-
}
|
|
2187
|
-
});
|
|
2188
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oidcDefaultSignInResolver;
|
|
2189
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
2190
|
-
catalogIdentityClient,
|
|
2191
|
-
tokenIssuer,
|
|
2192
|
-
logger
|
|
2193
|
-
});
|
|
2194
|
-
const provider = new OidcAuthProvider({
|
|
2195
|
-
clientId,
|
|
2196
|
-
clientSecret,
|
|
2197
|
-
callbackUrl,
|
|
2198
|
-
tokenSignedResponseAlg,
|
|
2199
|
-
metadataUrl,
|
|
2200
|
-
scope,
|
|
2201
|
-
prompt,
|
|
2202
|
-
signInResolver,
|
|
2203
|
-
authHandler,
|
|
2204
|
-
logger,
|
|
2205
|
-
tokenIssuer,
|
|
2206
|
-
catalogIdentityClient
|
|
2207
|
-
});
|
|
2208
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2209
|
-
disableRefresh: false,
|
|
2210
|
-
providerId,
|
|
2211
|
-
tokenIssuer,
|
|
2212
|
-
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
|
+
});
|
|
2213
1806
|
});
|
|
2214
|
-
}
|
|
2215
|
-
};
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
const createOidcProvider = oidc.create;
|
|
2216
1810
|
|
|
2217
1811
|
class OktaAuthProvider {
|
|
2218
1812
|
constructor(options) {
|
|
2219
|
-
this.
|
|
1813
|
+
this.store = {
|
|
2220
1814
|
store(_req, cb) {
|
|
2221
1815
|
cb(null, null);
|
|
2222
1816
|
},
|
|
@@ -2224,18 +1818,16 @@ class OktaAuthProvider {
|
|
|
2224
1818
|
cb(null, true);
|
|
2225
1819
|
}
|
|
2226
1820
|
};
|
|
2227
|
-
this.
|
|
2228
|
-
this.
|
|
2229
|
-
this.
|
|
2230
|
-
this.
|
|
2231
|
-
this._logger = options.logger;
|
|
2232
|
-
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({
|
|
2233
1825
|
clientID: options.clientId,
|
|
2234
1826
|
clientSecret: options.clientSecret,
|
|
2235
1827
|
callbackURL: options.callbackUrl,
|
|
2236
1828
|
audience: options.audience,
|
|
2237
1829
|
passReqToCallback: false,
|
|
2238
|
-
store: this.
|
|
1830
|
+
store: this.store,
|
|
2239
1831
|
response_type: "code"
|
|
2240
1832
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
2241
1833
|
done(void 0, {
|
|
@@ -2249,7 +1841,7 @@ class OktaAuthProvider {
|
|
|
2249
1841
|
});
|
|
2250
1842
|
}
|
|
2251
1843
|
async start(req) {
|
|
2252
|
-
return await executeRedirectStrategy(req, this.
|
|
1844
|
+
return await executeRedirectStrategy(req, this.strategy, {
|
|
2253
1845
|
accessType: "offline",
|
|
2254
1846
|
prompt: "consent",
|
|
2255
1847
|
scope: req.scope,
|
|
@@ -2257,15 +1849,15 @@ class OktaAuthProvider {
|
|
|
2257
1849
|
});
|
|
2258
1850
|
}
|
|
2259
1851
|
async handler(req) {
|
|
2260
|
-
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.
|
|
1852
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2261
1853
|
return {
|
|
2262
1854
|
response: await this.handleResult(result),
|
|
2263
1855
|
refreshToken: privateInfo.refreshToken
|
|
2264
1856
|
};
|
|
2265
1857
|
}
|
|
2266
1858
|
async refresh(req) {
|
|
2267
|
-
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(this.
|
|
2268
|
-
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);
|
|
2269
1861
|
return {
|
|
2270
1862
|
response: await this.handleResult({
|
|
2271
1863
|
fullProfile,
|
|
@@ -2276,12 +1868,7 @@ class OktaAuthProvider {
|
|
|
2276
1868
|
};
|
|
2277
1869
|
}
|
|
2278
1870
|
async handleResult(result) {
|
|
2279
|
-
const
|
|
2280
|
-
logger: this._logger,
|
|
2281
|
-
catalogIdentityClient: this._catalogIdentityClient,
|
|
2282
|
-
tokenIssuer: this._tokenIssuer
|
|
2283
|
-
};
|
|
2284
|
-
const { profile } = await this._authHandler(result, context);
|
|
1871
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2285
1872
|
const response = {
|
|
2286
1873
|
providerInfo: {
|
|
2287
1874
|
idToken: result.params.id_token,
|
|
@@ -2291,107 +1878,70 @@ class OktaAuthProvider {
|
|
|
2291
1878
|
},
|
|
2292
1879
|
profile
|
|
2293
1880
|
};
|
|
2294
|
-
if (this.
|
|
2295
|
-
response.backstageIdentity = await this.
|
|
1881
|
+
if (this.signInResolver) {
|
|
1882
|
+
response.backstageIdentity = await this.signInResolver({
|
|
2296
1883
|
result,
|
|
2297
1884
|
profile
|
|
2298
|
-
},
|
|
1885
|
+
}, this.resolverContext);
|
|
2299
1886
|
}
|
|
2300
1887
|
return response;
|
|
2301
1888
|
}
|
|
2302
1889
|
}
|
|
2303
|
-
const
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
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
|
+
};
|
|
2311
1934
|
}
|
|
2312
|
-
});
|
|
2313
|
-
const claims = getEntityClaims(entity);
|
|
2314
|
-
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
2315
|
-
return { id: entity.metadata.name, entity, token };
|
|
2316
|
-
};
|
|
2317
|
-
const oktaDefaultSignInResolver = async (info, ctx) => {
|
|
2318
|
-
const { profile } = info;
|
|
2319
|
-
if (!profile.email) {
|
|
2320
|
-
throw new Error("Okta profile contained no email");
|
|
2321
1935
|
}
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
namespace: catalogModel.DEFAULT_NAMESPACE,
|
|
2326
|
-
name: userId
|
|
2327
|
-
});
|
|
2328
|
-
const token = await ctx.tokenIssuer.issueToken({
|
|
2329
|
-
claims: {
|
|
2330
|
-
sub: entityRef,
|
|
2331
|
-
ent: [entityRef]
|
|
2332
|
-
}
|
|
2333
|
-
});
|
|
2334
|
-
return { id: userId, token };
|
|
2335
|
-
};
|
|
2336
|
-
const createOktaProvider = (_options) => {
|
|
2337
|
-
return ({
|
|
2338
|
-
providerId,
|
|
2339
|
-
globalConfig,
|
|
2340
|
-
config,
|
|
2341
|
-
tokenIssuer,
|
|
2342
|
-
tokenManager,
|
|
2343
|
-
catalogApi,
|
|
2344
|
-
logger
|
|
2345
|
-
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2346
|
-
var _a, _b;
|
|
2347
|
-
const clientId = envConfig.getString("clientId");
|
|
2348
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
2349
|
-
const audience = envConfig.getString("audience");
|
|
2350
|
-
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
2351
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
2352
|
-
if (!audience.startsWith("https://")) {
|
|
2353
|
-
throw new Error("URL for 'audience' must start with 'https://'.");
|
|
2354
|
-
}
|
|
2355
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2356
|
-
catalogApi,
|
|
2357
|
-
tokenManager
|
|
2358
|
-
});
|
|
2359
|
-
const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({ fullProfile, params }) => ({
|
|
2360
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
2361
|
-
});
|
|
2362
|
-
const signInResolverFn = (_b = (_a = _options == null ? void 0 : _options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oktaDefaultSignInResolver;
|
|
2363
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
2364
|
-
catalogIdentityClient,
|
|
2365
|
-
tokenIssuer,
|
|
2366
|
-
logger
|
|
2367
|
-
});
|
|
2368
|
-
const provider = new OktaAuthProvider({
|
|
2369
|
-
audience,
|
|
2370
|
-
clientId,
|
|
2371
|
-
clientSecret,
|
|
2372
|
-
callbackUrl,
|
|
2373
|
-
authHandler,
|
|
2374
|
-
signInResolver,
|
|
2375
|
-
tokenIssuer,
|
|
2376
|
-
catalogIdentityClient,
|
|
2377
|
-
logger
|
|
2378
|
-
});
|
|
2379
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2380
|
-
disableRefresh: false,
|
|
2381
|
-
providerId,
|
|
2382
|
-
tokenIssuer,
|
|
2383
|
-
callbackUrl
|
|
2384
|
-
});
|
|
2385
|
-
});
|
|
2386
|
-
};
|
|
1936
|
+
});
|
|
1937
|
+
const createOktaProvider = okta.create;
|
|
1938
|
+
const oktaEmailSignInResolver = okta.resolvers.emailMatchingUserEntityAnnotation();
|
|
2387
1939
|
|
|
2388
1940
|
class OneLoginProvider {
|
|
2389
1941
|
constructor(options) {
|
|
2390
1942
|
this.signInResolver = options.signInResolver;
|
|
2391
1943
|
this.authHandler = options.authHandler;
|
|
2392
|
-
this.
|
|
2393
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2394
|
-
this.logger = options.logger;
|
|
1944
|
+
this.resolverContext = options.resolverContext;
|
|
2395
1945
|
this._strategy = new passportOneloginOauth.Strategy({
|
|
2396
1946
|
issuer: options.issuer,
|
|
2397
1947
|
clientID: options.clientId,
|
|
@@ -2437,12 +1987,7 @@ class OneLoginProvider {
|
|
|
2437
1987
|
};
|
|
2438
1988
|
}
|
|
2439
1989
|
async handleResult(result) {
|
|
2440
|
-
const
|
|
2441
|
-
logger: this.logger,
|
|
2442
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2443
|
-
tokenIssuer: this.tokenIssuer
|
|
2444
|
-
};
|
|
2445
|
-
const { profile } = await this.authHandler(result, context);
|
|
1990
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2446
1991
|
const response = {
|
|
2447
1992
|
providerInfo: {
|
|
2448
1993
|
idToken: result.params.id_token,
|
|
@@ -2456,71 +2001,48 @@ class OneLoginProvider {
|
|
|
2456
2001
|
response.backstageIdentity = await this.signInResolver({
|
|
2457
2002
|
result,
|
|
2458
2003
|
profile
|
|
2459
|
-
},
|
|
2004
|
+
}, this.resolverContext);
|
|
2460
2005
|
}
|
|
2461
2006
|
return response;
|
|
2462
2007
|
}
|
|
2463
2008
|
}
|
|
2464
|
-
const
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
const
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
tokenManager
|
|
2491
|
-
});
|
|
2492
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
2493
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
2494
|
-
});
|
|
2495
|
-
const signInResolver = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : defaultSignInResolver;
|
|
2496
|
-
const provider = new OneLoginProvider({
|
|
2497
|
-
clientId,
|
|
2498
|
-
clientSecret,
|
|
2499
|
-
callbackUrl,
|
|
2500
|
-
issuer,
|
|
2501
|
-
authHandler,
|
|
2502
|
-
signInResolver,
|
|
2503
|
-
tokenIssuer,
|
|
2504
|
-
catalogIdentityClient,
|
|
2505
|
-
logger
|
|
2506
|
-
});
|
|
2507
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2508
|
-
disableRefresh: false,
|
|
2509
|
-
providerId,
|
|
2510
|
-
tokenIssuer,
|
|
2511
|
-
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
|
+
});
|
|
2512
2035
|
});
|
|
2513
|
-
}
|
|
2514
|
-
};
|
|
2036
|
+
}
|
|
2037
|
+
});
|
|
2038
|
+
const createOneLoginProvider = onelogin.create;
|
|
2515
2039
|
|
|
2516
2040
|
class SamlAuthProvider {
|
|
2517
2041
|
constructor(options) {
|
|
2518
2042
|
this.appUrl = options.appUrl;
|
|
2519
2043
|
this.signInResolver = options.signInResolver;
|
|
2520
2044
|
this.authHandler = options.authHandler;
|
|
2521
|
-
this.
|
|
2522
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2523
|
-
this.logger = options.logger;
|
|
2045
|
+
this.resolverContext = options.resolverContext;
|
|
2524
2046
|
this.strategy = new passportSaml.Strategy({ ...options }, (fullProfile, done) => {
|
|
2525
2047
|
done(void 0, { fullProfile });
|
|
2526
2048
|
});
|
|
@@ -2531,13 +2053,8 @@ class SamlAuthProvider {
|
|
|
2531
2053
|
}
|
|
2532
2054
|
async frameHandler(req, res) {
|
|
2533
2055
|
try {
|
|
2534
|
-
const context = {
|
|
2535
|
-
logger: this.logger,
|
|
2536
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2537
|
-
tokenIssuer: this.tokenIssuer
|
|
2538
|
-
};
|
|
2539
2056
|
const { result } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2540
|
-
const { profile } = await this.authHandler(result,
|
|
2057
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2541
2058
|
const response = {
|
|
2542
2059
|
profile,
|
|
2543
2060
|
providerInfo: {}
|
|
@@ -2546,7 +2063,7 @@ class SamlAuthProvider {
|
|
|
2546
2063
|
const signInResponse = await this.signInResolver({
|
|
2547
2064
|
result,
|
|
2548
2065
|
profile
|
|
2549
|
-
},
|
|
2066
|
+
}, this.resolverContext);
|
|
2550
2067
|
response.backstageIdentity = prepareBackstageIdentityResponse(signInResponse);
|
|
2551
2068
|
}
|
|
2552
2069
|
return postMessageResponse(res, this.appUrl, {
|
|
@@ -2565,71 +2082,53 @@ class SamlAuthProvider {
|
|
|
2565
2082
|
res.end();
|
|
2566
2083
|
}
|
|
2567
2084
|
}
|
|
2568
|
-
const
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
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
|
+
};
|
|
2579
2127
|
}
|
|
2580
|
-
}
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
const
|
|
2584
|
-
return ({
|
|
2585
|
-
providerId,
|
|
2586
|
-
globalConfig,
|
|
2587
|
-
config,
|
|
2588
|
-
tokenIssuer,
|
|
2589
|
-
tokenManager,
|
|
2590
|
-
catalogApi,
|
|
2591
|
-
logger
|
|
2592
|
-
}) => {
|
|
2593
|
-
var _a, _b;
|
|
2594
|
-
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2595
|
-
catalogApi,
|
|
2596
|
-
tokenManager
|
|
2597
|
-
});
|
|
2598
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2599
|
-
profile: {
|
|
2600
|
-
email: fullProfile.email,
|
|
2601
|
-
displayName: fullProfile.displayName
|
|
2602
|
-
}
|
|
2603
|
-
});
|
|
2604
|
-
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : samlDefaultSignInResolver;
|
|
2605
|
-
const signInResolver = (info) => signInResolverFn(info, {
|
|
2606
|
-
catalogIdentityClient,
|
|
2607
|
-
tokenIssuer,
|
|
2608
|
-
logger
|
|
2609
|
-
});
|
|
2610
|
-
return new SamlAuthProvider({
|
|
2611
|
-
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
|
2612
|
-
entryPoint: config.getString("entryPoint"),
|
|
2613
|
-
logoutUrl: config.getOptionalString("logoutUrl"),
|
|
2614
|
-
audience: config.getOptionalString("audience"),
|
|
2615
|
-
issuer: config.getString("issuer"),
|
|
2616
|
-
cert: config.getString("cert"),
|
|
2617
|
-
privateKey: config.getOptionalString("privateKey"),
|
|
2618
|
-
authnContext: config.getOptionalStringArray("authnContext"),
|
|
2619
|
-
identifierFormat: config.getOptionalString("identifierFormat"),
|
|
2620
|
-
decryptionPvk: config.getOptionalString("decryptionPvk"),
|
|
2621
|
-
signatureAlgorithm: config.getOptionalString("signatureAlgorithm"),
|
|
2622
|
-
digestAlgorithm: config.getOptionalString("digestAlgorithm"),
|
|
2623
|
-
acceptedClockSkewMs: config.getOptionalNumber("acceptedClockSkewMs"),
|
|
2624
|
-
tokenIssuer,
|
|
2625
|
-
appUrl: globalConfig.appUrl,
|
|
2626
|
-
authHandler,
|
|
2627
|
-
signInResolver,
|
|
2628
|
-
logger,
|
|
2629
|
-
catalogIdentityClient
|
|
2630
|
-
});
|
|
2631
|
-
};
|
|
2632
|
-
};
|
|
2128
|
+
}
|
|
2129
|
+
});
|
|
2130
|
+
const createSamlProvider = saml.create;
|
|
2131
|
+
const samlNameIdEntityNameSignInResolver = saml.resolvers.nameIdMatchingUserEntityName();
|
|
2633
2132
|
|
|
2634
2133
|
const IAP_JWT_HEADER = "x-goog-iap-jwt-assertion";
|
|
2635
2134
|
|
|
@@ -2675,9 +2174,7 @@ class GcpIapProvider {
|
|
|
2675
2174
|
this.authHandler = options.authHandler;
|
|
2676
2175
|
this.signInResolver = options.signInResolver;
|
|
2677
2176
|
this.tokenValidator = options.tokenValidator;
|
|
2678
|
-
this.
|
|
2679
|
-
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2680
|
-
this.logger = options.logger;
|
|
2177
|
+
this.resolverContext = options.resolverContext;
|
|
2681
2178
|
}
|
|
2682
2179
|
async start() {
|
|
2683
2180
|
}
|
|
@@ -2685,13 +2182,8 @@ class GcpIapProvider {
|
|
|
2685
2182
|
}
|
|
2686
2183
|
async refresh(req, res) {
|
|
2687
2184
|
const result = await parseRequestToken(req.header(IAP_JWT_HEADER), this.tokenValidator);
|
|
2688
|
-
const
|
|
2689
|
-
|
|
2690
|
-
catalogIdentityClient: this.catalogIdentityClient,
|
|
2691
|
-
tokenIssuer: this.tokenIssuer
|
|
2692
|
-
};
|
|
2693
|
-
const { profile } = await this.authHandler(result, context);
|
|
2694
|
-
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);
|
|
2695
2187
|
const response = {
|
|
2696
2188
|
providerInfo: { iapToken: result.iapToken },
|
|
2697
2189
|
profile,
|
|
@@ -2700,27 +2192,42 @@ class GcpIapProvider {
|
|
|
2700
2192
|
res.json(response);
|
|
2701
2193
|
}
|
|
2702
2194
|
}
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
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
|
+
});
|
|
2724
2231
|
|
|
2725
2232
|
const factories = {
|
|
2726
2233
|
google: createGoogleProvider(),
|
|
@@ -3008,6 +2515,149 @@ class KeyStores {
|
|
|
3008
2515
|
}
|
|
3009
2516
|
}
|
|
3010
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
|
+
|
|
3011
2661
|
async function createRouter(options) {
|
|
3012
2662
|
const {
|
|
3013
2663
|
logger,
|
|
@@ -3069,7 +2719,13 @@ async function createRouter(options) {
|
|
|
3069
2719
|
tokenManager,
|
|
3070
2720
|
tokenIssuer,
|
|
3071
2721
|
discovery,
|
|
3072
|
-
catalogApi
|
|
2722
|
+
catalogApi,
|
|
2723
|
+
resolverContext: CatalogAuthResolverContext.create({
|
|
2724
|
+
logger,
|
|
2725
|
+
catalogApi,
|
|
2726
|
+
tokenIssuer,
|
|
2727
|
+
tokenManager
|
|
2728
|
+
})
|
|
3073
2729
|
});
|
|
3074
2730
|
const r = Router__default["default"]();
|
|
3075
2731
|
r.get("/start", provider.start.bind(provider));
|
|
@@ -3147,12 +2803,15 @@ exports.createSamlProvider = createSamlProvider;
|
|
|
3147
2803
|
exports.defaultAuthProviderFactories = factories;
|
|
3148
2804
|
exports.encodeState = encodeState;
|
|
3149
2805
|
exports.ensuresXRequestedWith = ensuresXRequestedWith;
|
|
2806
|
+
exports.getDefaultOwnershipEntityRefs = getDefaultOwnershipEntityRefs;
|
|
3150
2807
|
exports.getEntityClaims = getEntityClaims;
|
|
3151
2808
|
exports.googleEmailSignInResolver = googleEmailSignInResolver;
|
|
3152
2809
|
exports.microsoftEmailSignInResolver = microsoftEmailSignInResolver;
|
|
3153
2810
|
exports.oktaEmailSignInResolver = oktaEmailSignInResolver;
|
|
3154
2811
|
exports.postMessageResponse = postMessageResponse;
|
|
3155
2812
|
exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
|
|
2813
|
+
exports.providers = providers;
|
|
3156
2814
|
exports.readState = readState;
|
|
2815
|
+
exports.samlNameIdEntityNameSignInResolver = samlNameIdEntityNameSignInResolver;
|
|
3157
2816
|
exports.verifyNonce = verifyNonce;
|
|
3158
2817
|
//# sourceMappingURL=index.cjs.js.map
|