@backstage/plugin-auth-backend 0.17.5-next.2 → 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 CHANGED
@@ -1,5 +1,22 @@
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
+
3
20
  ## 0.17.5-next.2
4
21
 
5
22
  ### 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