@backstage/plugin-auth-backend 0.22.4-next.1 → 0.22.5-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/config.d.ts +0 -9
- package/dist/index.cjs.js +131 -519
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +28 -16
- package/package.json +24 -22
package/dist/index.cjs.js
CHANGED
|
@@ -15,8 +15,8 @@ var url = require('url');
|
|
|
15
15
|
var errors = require('@backstage/errors');
|
|
16
16
|
var jose = require('jose');
|
|
17
17
|
var pluginAuthBackendModuleAwsAlbProvider = require('@backstage/plugin-auth-backend-module-aws-alb-provider');
|
|
18
|
-
var
|
|
19
|
-
var
|
|
18
|
+
var pluginAuthBackendModuleBitbucketProvider = require('@backstage/plugin-auth-backend-module-bitbucket-provider');
|
|
19
|
+
var pluginAuthBackendModuleCloudflareAccessProvider = require('@backstage/plugin-auth-backend-module-cloudflare-access-provider');
|
|
20
20
|
var pluginAuthBackendModuleGcpIapProvider = require('@backstage/plugin-auth-backend-module-gcp-iap-provider');
|
|
21
21
|
var pluginAuthBackendModuleGithubProvider = require('@backstage/plugin-auth-backend-module-github-provider');
|
|
22
22
|
var pluginAuthBackendModuleGitlabProvider = require('@backstage/plugin-auth-backend-module-gitlab-provider');
|
|
@@ -29,6 +29,8 @@ var pluginAuthBackendModuleOktaProvider = require('@backstage/plugin-auth-backen
|
|
|
29
29
|
var passportOneloginOauth = require('passport-onelogin-oauth');
|
|
30
30
|
var passportSaml = require('@node-saml/passport-saml');
|
|
31
31
|
var passportOauth2 = require('passport-oauth2');
|
|
32
|
+
var fetch = require('node-fetch');
|
|
33
|
+
var pluginAuthBackendModuleAzureEasyauthProvider = require('@backstage/plugin-auth-backend-module-azure-easyauth-provider');
|
|
32
34
|
var catalogClient = require('@backstage/catalog-client');
|
|
33
35
|
var minimatch = require('minimatch');
|
|
34
36
|
var catalogModel = require('@backstage/catalog-model');
|
|
@@ -219,10 +221,10 @@ const ensuresXRequestedWith = (req) => {
|
|
|
219
221
|
|
|
220
222
|
const prepareBackstageIdentityResponse = pluginAuthNode.prepareBackstageIdentityResponse;
|
|
221
223
|
|
|
222
|
-
var __defProp$
|
|
223
|
-
var __defNormalProp$
|
|
224
|
-
var __publicField$
|
|
225
|
-
__defNormalProp$
|
|
224
|
+
var __defProp$9 = Object.defineProperty;
|
|
225
|
+
var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
226
|
+
var __publicField$9 = (obj, key, value) => {
|
|
227
|
+
__defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
226
228
|
return value;
|
|
227
229
|
};
|
|
228
230
|
const THOUSAND_DAYS_MS = 1e3 * 24 * 60 * 60 * 1e3;
|
|
@@ -231,8 +233,8 @@ class OAuthAdapter {
|
|
|
231
233
|
constructor(handlers, options) {
|
|
232
234
|
this.handlers = handlers;
|
|
233
235
|
this.options = options;
|
|
234
|
-
__publicField$
|
|
235
|
-
__publicField$
|
|
236
|
+
__publicField$9(this, "baseCookieOptions");
|
|
237
|
+
__publicField$9(this, "setNonceCookie", (res, nonce, cookieConfig) => {
|
|
236
238
|
res.cookie(`${this.options.providerId}-nonce`, nonce, {
|
|
237
239
|
maxAge: TEN_MINUTES_MS,
|
|
238
240
|
...this.baseCookieOptions,
|
|
@@ -240,34 +242,34 @@ class OAuthAdapter {
|
|
|
240
242
|
path: `${cookieConfig.path}/handler`
|
|
241
243
|
});
|
|
242
244
|
});
|
|
243
|
-
__publicField$
|
|
245
|
+
__publicField$9(this, "setGrantedScopeCookie", (res, scope, cookieConfig) => {
|
|
244
246
|
res.cookie(`${this.options.providerId}-granted-scope`, scope, {
|
|
245
247
|
maxAge: THOUSAND_DAYS_MS,
|
|
246
248
|
...this.baseCookieOptions,
|
|
247
249
|
...cookieConfig
|
|
248
250
|
});
|
|
249
251
|
});
|
|
250
|
-
__publicField$
|
|
252
|
+
__publicField$9(this, "getRefreshTokenFromCookie", (req) => {
|
|
251
253
|
return req.cookies[`${this.options.providerId}-refresh-token`];
|
|
252
254
|
});
|
|
253
|
-
__publicField$
|
|
255
|
+
__publicField$9(this, "getGrantedScopeFromCookie", (req) => {
|
|
254
256
|
return req.cookies[`${this.options.providerId}-granted-scope`];
|
|
255
257
|
});
|
|
256
|
-
__publicField$
|
|
258
|
+
__publicField$9(this, "setRefreshTokenCookie", (res, refreshToken, cookieConfig) => {
|
|
257
259
|
res.cookie(`${this.options.providerId}-refresh-token`, refreshToken, {
|
|
258
260
|
maxAge: THOUSAND_DAYS_MS,
|
|
259
261
|
...this.baseCookieOptions,
|
|
260
262
|
...cookieConfig
|
|
261
263
|
});
|
|
262
264
|
});
|
|
263
|
-
__publicField$
|
|
265
|
+
__publicField$9(this, "removeRefreshTokenCookie", (res, cookieConfig) => {
|
|
264
266
|
res.cookie(`${this.options.providerId}-refresh-token`, "", {
|
|
265
267
|
maxAge: 0,
|
|
266
268
|
...this.baseCookieOptions,
|
|
267
269
|
...cookieConfig
|
|
268
270
|
});
|
|
269
271
|
});
|
|
270
|
-
__publicField$
|
|
272
|
+
__publicField$9(this, "getCookieConfig", (origin) => {
|
|
271
273
|
return this.options.cookieConfigurer({
|
|
272
274
|
providerId: this.options.providerId,
|
|
273
275
|
baseUrl: this.options.baseUrl,
|
|
@@ -565,21 +567,21 @@ const executeFetchUserProfileStrategy = async (providerStrategy, accessToken) =>
|
|
|
565
567
|
});
|
|
566
568
|
};
|
|
567
569
|
|
|
568
|
-
var __defProp$
|
|
569
|
-
var __defNormalProp$
|
|
570
|
-
var __publicField$
|
|
571
|
-
__defNormalProp$
|
|
570
|
+
var __defProp$8 = Object.defineProperty;
|
|
571
|
+
var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
572
|
+
var __publicField$8 = (obj, key, value) => {
|
|
573
|
+
__defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
572
574
|
return value;
|
|
573
575
|
};
|
|
574
576
|
class Auth0AuthProvider {
|
|
575
577
|
constructor(options) {
|
|
576
|
-
__publicField$
|
|
577
|
-
__publicField$
|
|
578
|
-
__publicField$
|
|
579
|
-
__publicField$
|
|
580
|
-
__publicField$
|
|
581
|
-
__publicField$
|
|
582
|
-
__publicField$
|
|
578
|
+
__publicField$8(this, "_strategy");
|
|
579
|
+
__publicField$8(this, "signInResolver");
|
|
580
|
+
__publicField$8(this, "authHandler");
|
|
581
|
+
__publicField$8(this, "resolverContext");
|
|
582
|
+
__publicField$8(this, "audience");
|
|
583
|
+
__publicField$8(this, "connection");
|
|
584
|
+
__publicField$8(this, "connectionScope");
|
|
583
585
|
/**
|
|
584
586
|
* Due to passport-auth0 forcing options.state = true,
|
|
585
587
|
* passport-oauth2 requires express-session to be installed
|
|
@@ -588,7 +590,7 @@ class Auth0AuthProvider {
|
|
|
588
590
|
* passport-oauth2, which is the StateStore implementation used when options.state = false,
|
|
589
591
|
* allowing us to avoid using express-session in order to integrate with auth0.
|
|
590
592
|
*/
|
|
591
|
-
__publicField$
|
|
593
|
+
__publicField$8(this, "store", {
|
|
592
594
|
store(_req, cb) {
|
|
593
595
|
cb(null, null);
|
|
594
596
|
},
|
|
@@ -740,370 +742,34 @@ const awsAlb = createAuthProviderIntegration({
|
|
|
740
742
|
}
|
|
741
743
|
});
|
|
742
744
|
|
|
743
|
-
var __defProp$a = Object.defineProperty;
|
|
744
|
-
var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
745
|
-
var __publicField$a = (obj, key, value) => {
|
|
746
|
-
__defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
747
|
-
return value;
|
|
748
|
-
};
|
|
749
|
-
class BitbucketAuthProvider {
|
|
750
|
-
constructor(options) {
|
|
751
|
-
__publicField$a(this, "_strategy");
|
|
752
|
-
__publicField$a(this, "signInResolver");
|
|
753
|
-
__publicField$a(this, "authHandler");
|
|
754
|
-
__publicField$a(this, "resolverContext");
|
|
755
|
-
this.signInResolver = options.signInResolver;
|
|
756
|
-
this.authHandler = options.authHandler;
|
|
757
|
-
this.resolverContext = options.resolverContext;
|
|
758
|
-
this._strategy = new passportBitbucketOauth2.Strategy(
|
|
759
|
-
{
|
|
760
|
-
clientID: options.clientId,
|
|
761
|
-
clientSecret: options.clientSecret,
|
|
762
|
-
callbackURL: options.callbackUrl,
|
|
763
|
-
passReqToCallback: false
|
|
764
|
-
},
|
|
765
|
-
(accessToken, refreshToken, params, fullProfile, done) => {
|
|
766
|
-
done(
|
|
767
|
-
void 0,
|
|
768
|
-
{
|
|
769
|
-
fullProfile,
|
|
770
|
-
params,
|
|
771
|
-
accessToken,
|
|
772
|
-
refreshToken
|
|
773
|
-
},
|
|
774
|
-
{
|
|
775
|
-
refreshToken
|
|
776
|
-
}
|
|
777
|
-
);
|
|
778
|
-
}
|
|
779
|
-
);
|
|
780
|
-
}
|
|
781
|
-
async start(req) {
|
|
782
|
-
return await executeRedirectStrategy(req, this._strategy, {
|
|
783
|
-
accessType: "offline",
|
|
784
|
-
prompt: "consent",
|
|
785
|
-
scope: req.scope,
|
|
786
|
-
state: encodeState(req.state)
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
|
-
async handler(req) {
|
|
790
|
-
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
791
|
-
return {
|
|
792
|
-
response: await this.handleResult(result),
|
|
793
|
-
refreshToken: privateInfo.refreshToken
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
async refresh(req) {
|
|
797
|
-
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(
|
|
798
|
-
this._strategy,
|
|
799
|
-
req.refreshToken,
|
|
800
|
-
req.scope
|
|
801
|
-
);
|
|
802
|
-
const fullProfile = await executeFetchUserProfileStrategy(
|
|
803
|
-
this._strategy,
|
|
804
|
-
accessToken
|
|
805
|
-
);
|
|
806
|
-
return {
|
|
807
|
-
response: await this.handleResult({
|
|
808
|
-
fullProfile,
|
|
809
|
-
params,
|
|
810
|
-
accessToken
|
|
811
|
-
}),
|
|
812
|
-
refreshToken
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
|
-
async handleResult(result) {
|
|
816
|
-
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
817
|
-
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
818
|
-
const response = {
|
|
819
|
-
providerInfo: {
|
|
820
|
-
idToken: result.params.id_token,
|
|
821
|
-
accessToken: result.accessToken,
|
|
822
|
-
scope: result.params.scope,
|
|
823
|
-
expiresInSeconds: result.params.expires_in
|
|
824
|
-
},
|
|
825
|
-
profile
|
|
826
|
-
};
|
|
827
|
-
if (this.signInResolver) {
|
|
828
|
-
response.backstageIdentity = await this.signInResolver(
|
|
829
|
-
{
|
|
830
|
-
result,
|
|
831
|
-
profile
|
|
832
|
-
},
|
|
833
|
-
this.resolverContext
|
|
834
|
-
);
|
|
835
|
-
}
|
|
836
|
-
return response;
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
745
|
const bitbucket = createAuthProviderIntegration({
|
|
840
746
|
create(options) {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
847
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
848
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
849
|
-
});
|
|
850
|
-
const provider = new BitbucketAuthProvider({
|
|
851
|
-
clientId,
|
|
852
|
-
clientSecret,
|
|
853
|
-
callbackUrl,
|
|
854
|
-
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
855
|
-
authHandler,
|
|
856
|
-
resolverContext
|
|
857
|
-
});
|
|
858
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
859
|
-
providerId,
|
|
860
|
-
callbackUrl
|
|
861
|
-
});
|
|
747
|
+
var _a;
|
|
748
|
+
return pluginAuthNode.createOAuthProviderFactory({
|
|
749
|
+
authenticator: pluginAuthBackendModuleBitbucketProvider.bitbucketAuthenticator,
|
|
750
|
+
profileTransform: adaptLegacyOAuthHandler(options == null ? void 0 : options.authHandler),
|
|
751
|
+
signInResolver: adaptLegacyOAuthSignInResolver((_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver)
|
|
862
752
|
});
|
|
863
753
|
},
|
|
864
|
-
resolvers: {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
usernameMatchingUserEntityAnnotation() {
|
|
869
|
-
return async (info, ctx) => {
|
|
870
|
-
const { result } = info;
|
|
871
|
-
if (!result.fullProfile.username) {
|
|
872
|
-
throw new Error("Bitbucket profile contained no Username");
|
|
873
|
-
}
|
|
874
|
-
return ctx.signInWithCatalogUser({
|
|
875
|
-
annotations: {
|
|
876
|
-
"bitbucket.org/username": result.fullProfile.username
|
|
877
|
-
}
|
|
878
|
-
});
|
|
879
|
-
};
|
|
880
|
-
},
|
|
881
|
-
/**
|
|
882
|
-
* Looks up the user by matching their user ID to the `bitbucket.org/user-id` annotation.
|
|
883
|
-
*/
|
|
884
|
-
userIdMatchingUserEntityAnnotation() {
|
|
885
|
-
return async (info, ctx) => {
|
|
886
|
-
const { result } = info;
|
|
887
|
-
if (!result.fullProfile.id) {
|
|
888
|
-
throw new Error("Bitbucket profile contained no User ID");
|
|
889
|
-
}
|
|
890
|
-
return ctx.signInWithCatalogUser({
|
|
891
|
-
annotations: {
|
|
892
|
-
"bitbucket.org/user-id": result.fullProfile.id
|
|
893
|
-
}
|
|
894
|
-
});
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
}
|
|
754
|
+
resolvers: adaptOAuthSignInResolverToLegacy({
|
|
755
|
+
userIdMatchingUserEntityAnnotation: pluginAuthBackendModuleBitbucketProvider.bitbucketSignInResolvers.userIdMatchingUserEntityAnnotation(),
|
|
756
|
+
usernameMatchingUserEntityAnnotation: pluginAuthBackendModuleBitbucketProvider.bitbucketSignInResolvers.usernameMatchingUserEntityAnnotation()
|
|
757
|
+
})
|
|
898
758
|
});
|
|
899
759
|
|
|
900
|
-
const commonByEmailLocalPartResolver = async (info, ctx) => {
|
|
901
|
-
const { profile } = info;
|
|
902
|
-
if (!profile.email) {
|
|
903
|
-
throw new Error("Login failed, user profile does not contain an email");
|
|
904
|
-
}
|
|
905
|
-
const [localPart] = profile.email.split("@");
|
|
906
|
-
return ctx.signInWithCatalogUser({
|
|
907
|
-
entityRef: { name: localPart }
|
|
908
|
-
});
|
|
909
|
-
};
|
|
910
|
-
const commonByEmailResolver = async (info, ctx) => {
|
|
911
|
-
const { profile } = info;
|
|
912
|
-
if (!profile.email) {
|
|
913
|
-
throw new Error("Login failed, user profile does not contain an email");
|
|
914
|
-
}
|
|
915
|
-
return ctx.signInWithCatalogUser({
|
|
916
|
-
filter: {
|
|
917
|
-
"spec.profile.email": profile.email
|
|
918
|
-
}
|
|
919
|
-
});
|
|
920
|
-
};
|
|
921
|
-
|
|
922
|
-
var __defProp$9 = Object.defineProperty;
|
|
923
|
-
var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
924
|
-
var __publicField$9 = (obj, key, value) => {
|
|
925
|
-
__defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
926
|
-
return value;
|
|
927
|
-
};
|
|
928
|
-
const CF_JWT_HEADER = "cf-access-jwt-assertion";
|
|
929
|
-
const COOKIE_AUTH_NAME = "CF_Authorization";
|
|
930
|
-
const CACHE_PREFIX = "providers/cloudflare-access/profile-v1";
|
|
931
|
-
class CloudflareAccessAuthProvider {
|
|
932
|
-
constructor(options) {
|
|
933
|
-
__publicField$9(this, "teamName");
|
|
934
|
-
__publicField$9(this, "serviceTokens");
|
|
935
|
-
__publicField$9(this, "resolverContext");
|
|
936
|
-
__publicField$9(this, "authHandler");
|
|
937
|
-
__publicField$9(this, "signInResolver");
|
|
938
|
-
__publicField$9(this, "jwtKeySet");
|
|
939
|
-
__publicField$9(this, "cache");
|
|
940
|
-
this.teamName = options.teamName;
|
|
941
|
-
this.serviceTokens = options.serviceTokens;
|
|
942
|
-
this.authHandler = options.authHandler;
|
|
943
|
-
this.signInResolver = options.signInResolver;
|
|
944
|
-
this.resolverContext = options.resolverContext;
|
|
945
|
-
this.jwtKeySet = jose.createRemoteJWKSet(
|
|
946
|
-
new URL(
|
|
947
|
-
`https://${this.teamName}.cloudflareaccess.com/cdn-cgi/access/certs`
|
|
948
|
-
)
|
|
949
|
-
);
|
|
950
|
-
this.cache = options.cache;
|
|
951
|
-
}
|
|
952
|
-
frameHandler() {
|
|
953
|
-
return Promise.resolve();
|
|
954
|
-
}
|
|
955
|
-
async refresh(req, res) {
|
|
956
|
-
const result = await this.getResult(req);
|
|
957
|
-
const response = await this.handleResult(result);
|
|
958
|
-
res.json(response);
|
|
959
|
-
}
|
|
960
|
-
start() {
|
|
961
|
-
return Promise.resolve();
|
|
962
|
-
}
|
|
963
|
-
async getIdentityProfile(jwt) {
|
|
964
|
-
const headers = new fetch.Headers();
|
|
965
|
-
headers.set(CF_JWT_HEADER, jwt);
|
|
966
|
-
headers.set("cookie", `${COOKIE_AUTH_NAME}=${jwt}`);
|
|
967
|
-
try {
|
|
968
|
-
const res = await fetch__default.default(
|
|
969
|
-
`https://${this.teamName}.cloudflareaccess.com/cdn-cgi/access/get-identity`,
|
|
970
|
-
{ headers }
|
|
971
|
-
);
|
|
972
|
-
if (!res.ok) {
|
|
973
|
-
throw await errors.ResponseError.fromResponse(res);
|
|
974
|
-
}
|
|
975
|
-
const cfIdentity = await res.json();
|
|
976
|
-
return cfIdentity;
|
|
977
|
-
} catch (err) {
|
|
978
|
-
throw new errors.ForwardedError("getIdentityProfile failed", err);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
async getResult(req) {
|
|
982
|
-
var _a, _b;
|
|
983
|
-
let jwt = req.header(CF_JWT_HEADER);
|
|
984
|
-
if (!jwt) {
|
|
985
|
-
jwt = req.cookies.CF_Authorization;
|
|
986
|
-
}
|
|
987
|
-
if (!jwt) {
|
|
988
|
-
throw new errors.AuthenticationError(
|
|
989
|
-
`Missing ${CF_JWT_HEADER} from Cloudflare Access`
|
|
990
|
-
);
|
|
991
|
-
}
|
|
992
|
-
const verifyResult = await jose.jwtVerify(jwt, this.jwtKeySet, {
|
|
993
|
-
issuer: `https://${this.teamName}.cloudflareaccess.com`
|
|
994
|
-
});
|
|
995
|
-
const isServiceToken = !verifyResult.payload.sub;
|
|
996
|
-
const subject = isServiceToken ? verifyResult.payload.common_name : verifyResult.payload.sub;
|
|
997
|
-
if (!subject) {
|
|
998
|
-
throw new errors.AuthenticationError(
|
|
999
|
-
`Missing both sub and common_name from Cloudflare Access JWT`
|
|
1000
|
-
);
|
|
1001
|
-
}
|
|
1002
|
-
const serviceToken = this.serviceTokens.find((st) => st.token === subject);
|
|
1003
|
-
if (isServiceToken && !serviceToken) {
|
|
1004
|
-
throw new errors.AuthenticationError(
|
|
1005
|
-
`${subject} is not a permitted Service Token.`
|
|
1006
|
-
);
|
|
1007
|
-
}
|
|
1008
|
-
const cacheKey = `${CACHE_PREFIX}/${subject}`;
|
|
1009
|
-
const cfAccessResultStr = await ((_a = this.cache) == null ? void 0 : _a.get(cacheKey));
|
|
1010
|
-
if (typeof cfAccessResultStr === "string") {
|
|
1011
|
-
const result = JSON.parse(cfAccessResultStr);
|
|
1012
|
-
return {
|
|
1013
|
-
...result,
|
|
1014
|
-
token: jwt
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
const claims = verifyResult.payload;
|
|
1018
|
-
try {
|
|
1019
|
-
let cfIdentity;
|
|
1020
|
-
if (serviceToken) {
|
|
1021
|
-
cfIdentity = {
|
|
1022
|
-
id: subject,
|
|
1023
|
-
name: "Bot",
|
|
1024
|
-
email: serviceToken.subject,
|
|
1025
|
-
groups: []
|
|
1026
|
-
};
|
|
1027
|
-
} else {
|
|
1028
|
-
cfIdentity = await this.getIdentityProfile(jwt);
|
|
1029
|
-
}
|
|
1030
|
-
const cfAccessResult = {
|
|
1031
|
-
claims,
|
|
1032
|
-
cfIdentity,
|
|
1033
|
-
expiresInSeconds: claims.exp - claims.iat
|
|
1034
|
-
};
|
|
1035
|
-
(_b = this.cache) == null ? void 0 : _b.set(cacheKey, JSON.stringify(cfAccessResult));
|
|
1036
|
-
return {
|
|
1037
|
-
...cfAccessResult,
|
|
1038
|
-
token: jwt
|
|
1039
|
-
};
|
|
1040
|
-
} catch (err) {
|
|
1041
|
-
throw new errors.ForwardedError(
|
|
1042
|
-
"Failed to populate access identity information",
|
|
1043
|
-
err
|
|
1044
|
-
);
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
async handleResult(result) {
|
|
1048
|
-
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1049
|
-
const backstageIdentity = await this.signInResolver(
|
|
1050
|
-
{
|
|
1051
|
-
result,
|
|
1052
|
-
profile
|
|
1053
|
-
},
|
|
1054
|
-
this.resolverContext
|
|
1055
|
-
);
|
|
1056
|
-
return {
|
|
1057
|
-
providerInfo: {
|
|
1058
|
-
expiresInSeconds: result.expiresInSeconds,
|
|
1059
|
-
claims: result.claims,
|
|
1060
|
-
cfAccessIdentityProfile: result.cfIdentity
|
|
1061
|
-
},
|
|
1062
|
-
backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
|
|
1063
|
-
profile
|
|
1064
|
-
};
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
760
|
const cfAccess = createAuthProviderIntegration({
|
|
1068
761
|
create(options) {
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
if (!options.signIn.resolver) {
|
|
1079
|
-
throw new Error(
|
|
1080
|
-
"SignInResolver is required to use this authentication provider"
|
|
1081
|
-
);
|
|
1082
|
-
}
|
|
1083
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ claims, cfIdentity }) => {
|
|
1084
|
-
return {
|
|
1085
|
-
profile: {
|
|
1086
|
-
email: claims.email,
|
|
1087
|
-
displayName: cfIdentity.name
|
|
1088
|
-
}
|
|
1089
|
-
};
|
|
1090
|
-
};
|
|
1091
|
-
return new CloudflareAccessAuthProvider({
|
|
1092
|
-
teamName,
|
|
1093
|
-
serviceTokens,
|
|
1094
|
-
signInResolver: options == null ? void 0 : options.signIn.resolver,
|
|
1095
|
-
authHandler,
|
|
1096
|
-
resolverContext,
|
|
1097
|
-
...options.cache && { cache: options.cache }
|
|
1098
|
-
});
|
|
1099
|
-
};
|
|
762
|
+
var _a;
|
|
763
|
+
return pluginAuthNode.createProxyAuthProviderFactory({
|
|
764
|
+
authenticator: pluginAuthBackendModuleCloudflareAccessProvider.createCloudflareAccessAuthenticator({
|
|
765
|
+
cache: options.cache
|
|
766
|
+
}),
|
|
767
|
+
profileTransform: options == null ? void 0 : options.authHandler,
|
|
768
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
769
|
+
signInResolverFactories: pluginAuthBackendModuleCloudflareAccessProvider.cloudflareAccessSignInResolvers
|
|
770
|
+
});
|
|
1100
771
|
},
|
|
1101
|
-
resolvers:
|
|
1102
|
-
/**
|
|
1103
|
-
* Looks up the user by matching their email to the entity email.
|
|
1104
|
-
*/
|
|
1105
|
-
emailMatchingUserEntityProfileEmail: () => commonByEmailResolver
|
|
1106
|
-
}
|
|
772
|
+
resolvers: pluginAuthBackendModuleCloudflareAccessProvider.cloudflareAccessSignInResolvers
|
|
1107
773
|
});
|
|
1108
774
|
|
|
1109
775
|
const gcpIap = createAuthProviderIntegration({
|
|
@@ -1236,6 +902,28 @@ const oauth2Proxy = createAuthProviderIntegration({
|
|
|
1236
902
|
}
|
|
1237
903
|
});
|
|
1238
904
|
|
|
905
|
+
const commonByEmailLocalPartResolver = async (info, ctx) => {
|
|
906
|
+
const { profile } = info;
|
|
907
|
+
if (!profile.email) {
|
|
908
|
+
throw new Error("Login failed, user profile does not contain an email");
|
|
909
|
+
}
|
|
910
|
+
const [localPart] = profile.email.split("@");
|
|
911
|
+
return ctx.signInWithCatalogUser({
|
|
912
|
+
entityRef: { name: localPart }
|
|
913
|
+
});
|
|
914
|
+
};
|
|
915
|
+
const commonByEmailResolver = async (info, ctx) => {
|
|
916
|
+
const { profile } = info;
|
|
917
|
+
if (!profile.email) {
|
|
918
|
+
throw new Error("Login failed, user profile does not contain an email");
|
|
919
|
+
}
|
|
920
|
+
return ctx.signInWithCatalogUser({
|
|
921
|
+
filter: {
|
|
922
|
+
"spec.profile.email": profile.email
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
};
|
|
926
|
+
|
|
1239
927
|
const oidc = createAuthProviderIntegration({
|
|
1240
928
|
create(options) {
|
|
1241
929
|
var _a;
|
|
@@ -1302,18 +990,18 @@ const okta = createAuthProviderIntegration({
|
|
|
1302
990
|
}
|
|
1303
991
|
});
|
|
1304
992
|
|
|
1305
|
-
var __defProp$
|
|
1306
|
-
var __defNormalProp$
|
|
1307
|
-
var __publicField$
|
|
1308
|
-
__defNormalProp$
|
|
993
|
+
var __defProp$7 = Object.defineProperty;
|
|
994
|
+
var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
995
|
+
var __publicField$7 = (obj, key, value) => {
|
|
996
|
+
__defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1309
997
|
return value;
|
|
1310
998
|
};
|
|
1311
999
|
class OneLoginProvider {
|
|
1312
1000
|
constructor(options) {
|
|
1313
|
-
__publicField$
|
|
1314
|
-
__publicField$
|
|
1315
|
-
__publicField$
|
|
1316
|
-
__publicField$
|
|
1001
|
+
__publicField$7(this, "_strategy");
|
|
1002
|
+
__publicField$7(this, "signInResolver");
|
|
1003
|
+
__publicField$7(this, "authHandler");
|
|
1004
|
+
__publicField$7(this, "resolverContext");
|
|
1317
1005
|
this.signInResolver = options.signInResolver;
|
|
1318
1006
|
this.authHandler = options.authHandler;
|
|
1319
1007
|
this.resolverContext = options.resolverContext;
|
|
@@ -1427,19 +1115,19 @@ const onelogin = createAuthProviderIntegration({
|
|
|
1427
1115
|
}
|
|
1428
1116
|
});
|
|
1429
1117
|
|
|
1430
|
-
var __defProp$
|
|
1431
|
-
var __defNormalProp$
|
|
1432
|
-
var __publicField$
|
|
1433
|
-
__defNormalProp$
|
|
1118
|
+
var __defProp$6 = Object.defineProperty;
|
|
1119
|
+
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1120
|
+
var __publicField$6 = (obj, key, value) => {
|
|
1121
|
+
__defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1434
1122
|
return value;
|
|
1435
1123
|
};
|
|
1436
1124
|
class SamlAuthProvider {
|
|
1437
1125
|
constructor(options) {
|
|
1438
|
-
__publicField$
|
|
1439
|
-
__publicField$
|
|
1440
|
-
__publicField$
|
|
1441
|
-
__publicField$
|
|
1442
|
-
__publicField$
|
|
1126
|
+
__publicField$6(this, "strategy");
|
|
1127
|
+
__publicField$6(this, "signInResolver");
|
|
1128
|
+
__publicField$6(this, "authHandler");
|
|
1129
|
+
__publicField$6(this, "resolverContext");
|
|
1130
|
+
__publicField$6(this, "appUrl");
|
|
1443
1131
|
this.appUrl = options.appUrl;
|
|
1444
1132
|
this.signInResolver = options.signInResolver;
|
|
1445
1133
|
this.authHandler = options.authHandler;
|
|
@@ -1543,19 +1231,19 @@ const saml = createAuthProviderIntegration({
|
|
|
1543
1231
|
}
|
|
1544
1232
|
});
|
|
1545
1233
|
|
|
1546
|
-
var __defProp$
|
|
1547
|
-
var __defNormalProp$
|
|
1548
|
-
var __publicField$
|
|
1549
|
-
__defNormalProp$
|
|
1234
|
+
var __defProp$5 = Object.defineProperty;
|
|
1235
|
+
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1236
|
+
var __publicField$5 = (obj, key, value) => {
|
|
1237
|
+
__defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1550
1238
|
return value;
|
|
1551
1239
|
};
|
|
1552
1240
|
class BitbucketServerAuthProvider {
|
|
1553
1241
|
constructor(options) {
|
|
1554
|
-
__publicField$
|
|
1555
|
-
__publicField$
|
|
1556
|
-
__publicField$
|
|
1557
|
-
__publicField$
|
|
1558
|
-
__publicField$
|
|
1242
|
+
__publicField$5(this, "signInResolver");
|
|
1243
|
+
__publicField$5(this, "authHandler");
|
|
1244
|
+
__publicField$5(this, "resolverContext");
|
|
1245
|
+
__publicField$5(this, "strategy");
|
|
1246
|
+
__publicField$5(this, "host");
|
|
1559
1247
|
this.signInResolver = options.signInResolver;
|
|
1560
1248
|
this.authHandler = options.authHandler;
|
|
1561
1249
|
this.resolverContext = options.resolverContext;
|
|
@@ -1720,112 +1408,16 @@ const bitbucketServer = createAuthProviderIntegration({
|
|
|
1720
1408
|
}
|
|
1721
1409
|
});
|
|
1722
1410
|
|
|
1723
|
-
var __defProp$5 = Object.defineProperty;
|
|
1724
|
-
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1725
|
-
var __publicField$5 = (obj, key, value) => {
|
|
1726
|
-
__defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1727
|
-
return value;
|
|
1728
|
-
};
|
|
1729
|
-
const ID_TOKEN_HEADER = "x-ms-token-aad-id-token";
|
|
1730
|
-
const ACCESS_TOKEN_HEADER = "x-ms-token-aad-access-token";
|
|
1731
|
-
class EasyAuthAuthProvider {
|
|
1732
|
-
constructor(options) {
|
|
1733
|
-
__publicField$5(this, "resolverContext");
|
|
1734
|
-
__publicField$5(this, "authHandler");
|
|
1735
|
-
__publicField$5(this, "signInResolver");
|
|
1736
|
-
this.authHandler = options.authHandler;
|
|
1737
|
-
this.signInResolver = options.signInResolver;
|
|
1738
|
-
this.resolverContext = options.resolverContext;
|
|
1739
|
-
}
|
|
1740
|
-
frameHandler() {
|
|
1741
|
-
return Promise.resolve(void 0);
|
|
1742
|
-
}
|
|
1743
|
-
async refresh(req, res) {
|
|
1744
|
-
const result = await this.getResult(req);
|
|
1745
|
-
const response = await this.handleResult(result);
|
|
1746
|
-
res.json(response);
|
|
1747
|
-
}
|
|
1748
|
-
start() {
|
|
1749
|
-
return Promise.resolve(void 0);
|
|
1750
|
-
}
|
|
1751
|
-
async getResult(req) {
|
|
1752
|
-
const idToken = req.header(ID_TOKEN_HEADER);
|
|
1753
|
-
const accessToken = req.header(ACCESS_TOKEN_HEADER);
|
|
1754
|
-
if (idToken === void 0) {
|
|
1755
|
-
throw new errors.AuthenticationError(`Missing ${ID_TOKEN_HEADER} header`);
|
|
1756
|
-
}
|
|
1757
|
-
return {
|
|
1758
|
-
fullProfile: this.idTokenToProfile(idToken),
|
|
1759
|
-
accessToken
|
|
1760
|
-
};
|
|
1761
|
-
}
|
|
1762
|
-
idTokenToProfile(idToken) {
|
|
1763
|
-
const claims = jose.decodeJwt(idToken);
|
|
1764
|
-
if (claims.ver !== "2.0") {
|
|
1765
|
-
throw new Error("id_token is not version 2.0 ");
|
|
1766
|
-
}
|
|
1767
|
-
return {
|
|
1768
|
-
id: claims.oid,
|
|
1769
|
-
displayName: claims.name,
|
|
1770
|
-
provider: "easyauth",
|
|
1771
|
-
emails: [{ value: claims.email }],
|
|
1772
|
-
username: claims.preferred_username
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
async handleResult(result) {
|
|
1776
|
-
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1777
|
-
const backstageIdentity = await this.signInResolver(
|
|
1778
|
-
{
|
|
1779
|
-
result,
|
|
1780
|
-
profile
|
|
1781
|
-
},
|
|
1782
|
-
this.resolverContext
|
|
1783
|
-
);
|
|
1784
|
-
return {
|
|
1785
|
-
providerInfo: {
|
|
1786
|
-
accessToken: result.accessToken
|
|
1787
|
-
},
|
|
1788
|
-
backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
|
|
1789
|
-
profile
|
|
1790
|
-
};
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
1411
|
const easyAuth = createAuthProviderIntegration({
|
|
1794
1412
|
create(options) {
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
);
|
|
1802
|
-
}
|
|
1803
|
-
const authHandler = (_a = options.authHandler) != null ? _a : async ({ fullProfile }) => ({
|
|
1804
|
-
profile: makeProfileInfo(fullProfile)
|
|
1805
|
-
});
|
|
1806
|
-
return new EasyAuthAuthProvider({
|
|
1807
|
-
signInResolver: options.signIn.resolver,
|
|
1808
|
-
authHandler,
|
|
1809
|
-
resolverContext
|
|
1810
|
-
});
|
|
1811
|
-
};
|
|
1413
|
+
var _a;
|
|
1414
|
+
return pluginAuthNode.createProxyAuthProviderFactory({
|
|
1415
|
+
authenticator: pluginAuthBackendModuleAzureEasyauthProvider.azureEasyAuthAuthenticator,
|
|
1416
|
+
profileTransform: options == null ? void 0 : options.authHandler,
|
|
1417
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver
|
|
1418
|
+
});
|
|
1812
1419
|
}
|
|
1813
1420
|
});
|
|
1814
|
-
function validateAppServiceConfiguration(env) {
|
|
1815
|
-
var _a, _b, _c;
|
|
1816
|
-
if (env.WEBSITE_SKU === void 0) {
|
|
1817
|
-
throw new Error("Backstage is not running on Azure App Services");
|
|
1818
|
-
}
|
|
1819
|
-
if (((_a = env.WEBSITE_AUTH_ENABLED) == null ? void 0 : _a.toLowerCase()) !== "true") {
|
|
1820
|
-
throw new Error("Azure App Services does not have authentication enabled");
|
|
1821
|
-
}
|
|
1822
|
-
if (((_b = env.WEBSITE_AUTH_DEFAULT_PROVIDER) == null ? void 0 : _b.toLowerCase()) !== "azureactivedirectory") {
|
|
1823
|
-
throw new Error("Authentication provider is not Entra ID");
|
|
1824
|
-
}
|
|
1825
|
-
if (((_c = process.env.WEBSITE_AUTH_TOKEN_STORE) == null ? void 0 : _c.toLowerCase()) !== "true") {
|
|
1826
|
-
throw new Error("Token Store is not enabled");
|
|
1827
|
-
}
|
|
1828
|
-
}
|
|
1829
1421
|
|
|
1830
1422
|
const providers = Object.freeze({
|
|
1831
1423
|
atlassian,
|
|
@@ -1968,12 +1560,13 @@ function getDefaultOwnershipEntityRefs(entity) {
|
|
|
1968
1560
|
return Array.from(/* @__PURE__ */ new Set([catalogModel.stringifyEntityRef(entity), ...membershipRefs]));
|
|
1969
1561
|
}
|
|
1970
1562
|
class CatalogAuthResolverContext {
|
|
1971
|
-
constructor(logger, tokenIssuer, catalogIdentityClient, catalogApi, auth) {
|
|
1563
|
+
constructor(logger, tokenIssuer, catalogIdentityClient, catalogApi, auth, ownershipResolver) {
|
|
1972
1564
|
this.logger = logger;
|
|
1973
1565
|
this.tokenIssuer = tokenIssuer;
|
|
1974
1566
|
this.catalogIdentityClient = catalogIdentityClient;
|
|
1975
1567
|
this.catalogApi = catalogApi;
|
|
1976
1568
|
this.auth = auth;
|
|
1569
|
+
this.ownershipResolver = ownershipResolver;
|
|
1977
1570
|
}
|
|
1978
1571
|
static create(options) {
|
|
1979
1572
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
@@ -1988,7 +1581,8 @@ class CatalogAuthResolverContext {
|
|
|
1988
1581
|
options.tokenIssuer,
|
|
1989
1582
|
catalogIdentityClient,
|
|
1990
1583
|
options.catalogApi,
|
|
1991
|
-
options.auth
|
|
1584
|
+
options.auth,
|
|
1585
|
+
options.ownershipResolver
|
|
1992
1586
|
);
|
|
1993
1587
|
}
|
|
1994
1588
|
async issueToken(params) {
|
|
@@ -2049,11 +1643,17 @@ class CatalogAuthResolverContext {
|
|
|
2049
1643
|
}
|
|
2050
1644
|
async signInWithCatalogUser(query) {
|
|
2051
1645
|
const { entity } = await this.findCatalogUser(query);
|
|
2052
|
-
|
|
1646
|
+
let ent;
|
|
1647
|
+
if (this.ownershipResolver) {
|
|
1648
|
+
const { ownershipEntityRefs } = await this.ownershipResolver.resolveOwnershipEntityRefs(entity);
|
|
1649
|
+
ent = ownershipEntityRefs;
|
|
1650
|
+
} else {
|
|
1651
|
+
ent = getDefaultOwnershipEntityRefs(entity);
|
|
1652
|
+
}
|
|
2053
1653
|
const token = await this.tokenIssuer.issueToken({
|
|
2054
1654
|
claims: {
|
|
2055
1655
|
sub: catalogModel.stringifyEntityRef(entity),
|
|
2056
|
-
ent
|
|
1656
|
+
ent
|
|
2057
1657
|
}
|
|
2058
1658
|
});
|
|
2059
1659
|
return { token };
|
|
@@ -2072,7 +1672,8 @@ function bindProviderRouters(targetRouter, options) {
|
|
|
2072
1672
|
httpAuth,
|
|
2073
1673
|
tokenManager,
|
|
2074
1674
|
tokenIssuer,
|
|
2075
|
-
catalogApi
|
|
1675
|
+
catalogApi,
|
|
1676
|
+
ownershipResolver
|
|
2076
1677
|
} = options;
|
|
2077
1678
|
const providersConfig = config.getOptionalConfig("auth.providers");
|
|
2078
1679
|
const isOriginAllowed = createOriginFilter(config);
|
|
@@ -2099,7 +1700,8 @@ function bindProviderRouters(targetRouter, options) {
|
|
|
2099
1700
|
tokenManager,
|
|
2100
1701
|
discovery,
|
|
2101
1702
|
auth,
|
|
2102
|
-
httpAuth
|
|
1703
|
+
httpAuth,
|
|
1704
|
+
ownershipResolver
|
|
2103
1705
|
})
|
|
2104
1706
|
});
|
|
2105
1707
|
const r = Router__default.default();
|
|
@@ -2413,7 +2015,7 @@ class DatabaseKeyStore {
|
|
|
2413
2015
|
var __defProp$2 = Object.defineProperty;
|
|
2414
2016
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
2415
2017
|
var __publicField$2 = (obj, key, value) => {
|
|
2416
|
-
__defNormalProp$2(obj,
|
|
2018
|
+
__defNormalProp$2(obj, key + "" , value);
|
|
2417
2019
|
return value;
|
|
2418
2020
|
};
|
|
2419
2021
|
class MemoryKeyStore {
|
|
@@ -2665,7 +2267,7 @@ var __accessCheck = (obj, member, msg) => {
|
|
|
2665
2267
|
};
|
|
2666
2268
|
var __privateGet = (obj, member, getter) => {
|
|
2667
2269
|
__accessCheck(obj, member, "read from private field");
|
|
2668
|
-
return
|
|
2270
|
+
return member.get(obj);
|
|
2669
2271
|
};
|
|
2670
2272
|
var __privateAdd = (obj, member, value) => {
|
|
2671
2273
|
if (member.has(obj))
|
|
@@ -2674,7 +2276,7 @@ var __privateAdd = (obj, member, value) => {
|
|
|
2674
2276
|
};
|
|
2675
2277
|
var __privateSet = (obj, member, value, setter) => {
|
|
2676
2278
|
__accessCheck(obj, member, "write to private field");
|
|
2677
|
-
|
|
2279
|
+
member.set(obj, value);
|
|
2678
2280
|
return value;
|
|
2679
2281
|
};
|
|
2680
2282
|
var _database, _promise;
|
|
@@ -2888,6 +2490,7 @@ const authPlugin = backendPluginApi.createBackendPlugin({
|
|
|
2888
2490
|
pluginId: "auth",
|
|
2889
2491
|
register(reg) {
|
|
2890
2492
|
const providers = /* @__PURE__ */ new Map();
|
|
2493
|
+
let ownershipResolver = void 0;
|
|
2891
2494
|
reg.registerExtensionPoint(pluginAuthNode.authProvidersExtensionPoint, {
|
|
2892
2495
|
registerProvider({ providerId, factory }) {
|
|
2893
2496
|
if (providers.has(providerId)) {
|
|
@@ -2898,6 +2501,14 @@ const authPlugin = backendPluginApi.createBackendPlugin({
|
|
|
2898
2501
|
providers.set(providerId, factory);
|
|
2899
2502
|
}
|
|
2900
2503
|
});
|
|
2504
|
+
reg.registerExtensionPoint(pluginAuthNode.authOwnershipResolutionExtensionPoint, {
|
|
2505
|
+
setAuthOwnershipResolver(resolver) {
|
|
2506
|
+
if (ownershipResolver) {
|
|
2507
|
+
throw new Error("Auth ownership resolver is already set");
|
|
2508
|
+
}
|
|
2509
|
+
ownershipResolver = resolver;
|
|
2510
|
+
}
|
|
2511
|
+
});
|
|
2901
2512
|
reg.registerInit({
|
|
2902
2513
|
deps: {
|
|
2903
2514
|
httpRouter: backendPluginApi.coreServices.httpRouter,
|
|
@@ -2931,7 +2542,8 @@ const authPlugin = backendPluginApi.createBackendPlugin({
|
|
|
2931
2542
|
httpAuth,
|
|
2932
2543
|
catalogApi,
|
|
2933
2544
|
providerFactories: Object.fromEntries(providers),
|
|
2934
|
-
disableDefaultProviderFactories: true
|
|
2545
|
+
disableDefaultProviderFactories: true,
|
|
2546
|
+
ownershipResolver
|
|
2935
2547
|
});
|
|
2936
2548
|
httpRouter.addAuthPolicy({
|
|
2937
2549
|
path: "/",
|