@backstage/plugin-auth-backend 0.17.5-next.1 → 0.18.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 +30 -0
- package/dist/index.cjs.js +168 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +26 -2
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @backstage/plugin-auth-backend
|
|
2
2
|
|
|
3
|
+
## 0.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/backend-common@0.18.2
|
|
13
|
+
- @backstage/catalog-model@1.2.0
|
|
14
|
+
- @backstage/catalog-client@1.3.1
|
|
15
|
+
- @backstage/config@1.0.6
|
|
16
|
+
- @backstage/errors@1.1.4
|
|
17
|
+
- @backstage/types@1.0.2
|
|
18
|
+
- @backstage/plugin-auth-node@0.2.11
|
|
19
|
+
|
|
20
|
+
## 0.17.5-next.2
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @backstage/backend-common@0.18.2-next.2
|
|
26
|
+
- @backstage/catalog-model@1.2.0-next.1
|
|
27
|
+
- @backstage/plugin-auth-node@0.2.11-next.2
|
|
28
|
+
- @backstage/catalog-client@1.3.1-next.1
|
|
29
|
+
- @backstage/config@1.0.6
|
|
30
|
+
- @backstage/errors@1.1.4
|
|
31
|
+
- @backstage/types@1.0.2
|
|
32
|
+
|
|
3
33
|
## 0.17.5-next.1
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -2755,11 +2755,178 @@ const saml = createAuthProviderIntegration({
|
|
|
2755
2755
|
}
|
|
2756
2756
|
});
|
|
2757
2757
|
|
|
2758
|
+
class BitbucketServerAuthProvider {
|
|
2759
|
+
constructor(options) {
|
|
2760
|
+
this.signInResolver = options.signInResolver;
|
|
2761
|
+
this.authHandler = options.authHandler;
|
|
2762
|
+
this.resolverContext = options.resolverContext;
|
|
2763
|
+
this.strategy = new OAuth2Strategy.Strategy(
|
|
2764
|
+
{
|
|
2765
|
+
authorizationURL: options.authorizationUrl,
|
|
2766
|
+
tokenURL: options.tokenUrl,
|
|
2767
|
+
clientID: options.clientId,
|
|
2768
|
+
clientSecret: options.clientSecret,
|
|
2769
|
+
callbackURL: options.callbackUrl
|
|
2770
|
+
},
|
|
2771
|
+
(accessToken, refreshToken, params, fullProfile, done) => {
|
|
2772
|
+
done(void 0, { fullProfile, params, accessToken }, { refreshToken });
|
|
2773
|
+
}
|
|
2774
|
+
);
|
|
2775
|
+
this.host = options.host;
|
|
2776
|
+
}
|
|
2777
|
+
async start(req) {
|
|
2778
|
+
return await executeRedirectStrategy(req, this.strategy, {
|
|
2779
|
+
accessType: "offline",
|
|
2780
|
+
prompt: "consent",
|
|
2781
|
+
scope: req.scope,
|
|
2782
|
+
state: encodeState(req.state)
|
|
2783
|
+
});
|
|
2784
|
+
}
|
|
2785
|
+
async handler(req) {
|
|
2786
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2787
|
+
return {
|
|
2788
|
+
response: await this.handleResult(result),
|
|
2789
|
+
refreshToken: privateInfo.refreshToken
|
|
2790
|
+
};
|
|
2791
|
+
}
|
|
2792
|
+
async refresh(req) {
|
|
2793
|
+
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(
|
|
2794
|
+
this.strategy,
|
|
2795
|
+
req.refreshToken,
|
|
2796
|
+
req.scope
|
|
2797
|
+
);
|
|
2798
|
+
const fullProfile = await executeFetchUserProfileStrategy(
|
|
2799
|
+
this.strategy,
|
|
2800
|
+
accessToken
|
|
2801
|
+
);
|
|
2802
|
+
return {
|
|
2803
|
+
response: await this.handleResult({
|
|
2804
|
+
fullProfile,
|
|
2805
|
+
params,
|
|
2806
|
+
accessToken
|
|
2807
|
+
}),
|
|
2808
|
+
refreshToken
|
|
2809
|
+
};
|
|
2810
|
+
}
|
|
2811
|
+
async handleResult(result) {
|
|
2812
|
+
result.fullProfile = await this.fetchProfile(result);
|
|
2813
|
+
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
2814
|
+
let backstageIdentity = void 0;
|
|
2815
|
+
if (this.signInResolver) {
|
|
2816
|
+
backstageIdentity = await this.signInResolver(
|
|
2817
|
+
{ result, profile },
|
|
2818
|
+
this.resolverContext
|
|
2819
|
+
);
|
|
2820
|
+
}
|
|
2821
|
+
return {
|
|
2822
|
+
providerInfo: {
|
|
2823
|
+
accessToken: result.accessToken,
|
|
2824
|
+
scope: result.params.scope,
|
|
2825
|
+
expiresInSeconds: result.params.expires_in
|
|
2826
|
+
},
|
|
2827
|
+
profile,
|
|
2828
|
+
backstageIdentity
|
|
2829
|
+
};
|
|
2830
|
+
}
|
|
2831
|
+
async fetchProfile(result) {
|
|
2832
|
+
let whoAmIResponse;
|
|
2833
|
+
try {
|
|
2834
|
+
whoAmIResponse = await fetch__default["default"](
|
|
2835
|
+
`https://${this.host}/plugins/servlet/applinks/whoami`,
|
|
2836
|
+
{
|
|
2837
|
+
headers: {
|
|
2838
|
+
Authorization: `Bearer ${result.accessToken}`
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
);
|
|
2842
|
+
} catch (e) {
|
|
2843
|
+
throw new Error(`Failed to retrieve the username of the logged in user`);
|
|
2844
|
+
}
|
|
2845
|
+
const username = whoAmIResponse.headers.get("X-Ausername");
|
|
2846
|
+
if (!username) {
|
|
2847
|
+
throw new Error(`Failed to retrieve the username of the logged in user`);
|
|
2848
|
+
}
|
|
2849
|
+
let userResponse;
|
|
2850
|
+
try {
|
|
2851
|
+
userResponse = await fetch__default["default"](
|
|
2852
|
+
`https://${this.host}/rest/api/latest/users/${username}?avatarSize=256`,
|
|
2853
|
+
{
|
|
2854
|
+
headers: {
|
|
2855
|
+
Authorization: `Bearer ${result.accessToken}`
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
);
|
|
2859
|
+
} catch (e) {
|
|
2860
|
+
throw new Error(`Failed to retrieve the user '${username}'`);
|
|
2861
|
+
}
|
|
2862
|
+
if (!userResponse.ok) {
|
|
2863
|
+
throw new Error(`Failed to retrieve the user '${username}'`);
|
|
2864
|
+
}
|
|
2865
|
+
const user = await userResponse.json();
|
|
2866
|
+
const passportProfile = {
|
|
2867
|
+
provider: "bitbucketServer",
|
|
2868
|
+
id: user.id.toString(),
|
|
2869
|
+
displayName: user.displayName,
|
|
2870
|
+
username: user.name,
|
|
2871
|
+
emails: [
|
|
2872
|
+
{
|
|
2873
|
+
value: user.emailAddress
|
|
2874
|
+
}
|
|
2875
|
+
]
|
|
2876
|
+
};
|
|
2877
|
+
if (user.avatarUrl) {
|
|
2878
|
+
passportProfile.photos = [
|
|
2879
|
+
{ value: `https://${this.host}${user.avatarUrl}` }
|
|
2880
|
+
];
|
|
2881
|
+
}
|
|
2882
|
+
return passportProfile;
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
const bitbucketServer = createAuthProviderIntegration({
|
|
2886
|
+
create(options) {
|
|
2887
|
+
return ({ providerId, globalConfig, config, resolverContext }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2888
|
+
var _a;
|
|
2889
|
+
const clientId = envConfig.getString("clientId");
|
|
2890
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
2891
|
+
const host = envConfig.getString("host");
|
|
2892
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
2893
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
2894
|
+
const authorizationUrl = `https://${host}/rest/oauth2/latest/authorize`;
|
|
2895
|
+
const tokenUrl = `https://${host}/rest/oauth2/latest/token`;
|
|
2896
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2897
|
+
profile: makeProfileInfo(fullProfile)
|
|
2898
|
+
});
|
|
2899
|
+
const provider = new BitbucketServerAuthProvider({
|
|
2900
|
+
callbackUrl,
|
|
2901
|
+
clientId,
|
|
2902
|
+
clientSecret,
|
|
2903
|
+
host,
|
|
2904
|
+
authorizationUrl,
|
|
2905
|
+
tokenUrl,
|
|
2906
|
+
authHandler,
|
|
2907
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
2908
|
+
resolverContext
|
|
2909
|
+
});
|
|
2910
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2911
|
+
providerId,
|
|
2912
|
+
callbackUrl
|
|
2913
|
+
});
|
|
2914
|
+
});
|
|
2915
|
+
},
|
|
2916
|
+
resolvers: {
|
|
2917
|
+
/**
|
|
2918
|
+
* Looks up the user by matching their email to the entity email.
|
|
2919
|
+
*/
|
|
2920
|
+
emailMatchingUserEntityProfileEmail: () => commonByEmailResolver
|
|
2921
|
+
}
|
|
2922
|
+
});
|
|
2923
|
+
|
|
2758
2924
|
const providers = Object.freeze({
|
|
2759
2925
|
atlassian,
|
|
2760
2926
|
auth0,
|
|
2761
2927
|
awsAlb,
|
|
2762
2928
|
bitbucket,
|
|
2929
|
+
bitbucketServer,
|
|
2763
2930
|
cfAccess,
|
|
2764
2931
|
gcpIap,
|
|
2765
2932
|
github,
|
|
@@ -2786,6 +2953,7 @@ const defaultAuthProviderFactories = {
|
|
|
2786
2953
|
onelogin: onelogin.create(),
|
|
2787
2954
|
awsalb: awsAlb.create(),
|
|
2788
2955
|
bitbucket: bitbucket.create(),
|
|
2956
|
+
bitbucketServer: bitbucketServer.create(),
|
|
2789
2957
|
atlassian: atlassian.create()
|
|
2790
2958
|
};
|
|
2791
2959
|
|