'use strict';

var jose = require('jose');
var errors = require('@backstage/errors');

class PassportHelpers {
  constructor() {
  }
  static transformProfile = (profile, idToken) => {
    let email = void 0;
    if (profile.emails && profile.emails.length > 0) {
      const [firstEmail] = profile.emails;
      email = firstEmail.value;
    } else if (profile.email) {
      email = profile.email;
    }
    let picture = void 0;
    if (profile.avatarUrl) {
      picture = profile.avatarUrl;
    } else if (profile.photos && profile.photos.length > 0) {
      const [firstPhoto] = profile.photos;
      picture = firstPhoto.value;
    } else if (profile.photo) {
      picture = profile.photo;
    }
    let displayName = profile.displayName ?? profile.username ?? profile.id;
    if ((!email || !picture || !displayName) && idToken) {
      try {
        const decoded = jose.decodeJwt(idToken);
        if (!email && decoded.email) {
          email = decoded.email;
        }
        if (!picture && decoded.picture) {
          picture = decoded.picture;
        }
        if (!displayName && decoded.name) {
          displayName = decoded.name;
        }
      } catch (e) {
        throw new errors.ForwardedError(
          `Failed to parse id token and get profile info`,
          e
        );
      }
    }
    return {
      email,
      picture,
      displayName
    };
  };
  static async executeRedirectStrategy(req, providerStrategy, options) {
    return new Promise((resolve, reject) => {
      const strategy = Object.create(providerStrategy);
      strategy.error = (error) => {
        reject(new Error(`Authentication failed, ${error.message ?? ""}`));
      };
      strategy.redirect = (url, status) => {
        resolve({ url, status: status ?? void 0 });
      };
      strategy.authenticate(req, { ...options });
    });
  }
  static async executeFrameHandlerStrategy(req, providerStrategy, options) {
    return new Promise((resolve, reject) => {
      const strategy = Object.create(providerStrategy);
      strategy.success = (result, privateInfo) => {
        resolve({ result, privateInfo });
      };
      strategy.fail = (info) => {
        reject(new Error(`Authentication rejected, ${info.message ?? ""}`));
      };
      strategy.error = (error) => {
        let message = `Authentication failed, ${error.message}`;
        if (error.oauthError?.data) {
          try {
            const errorData = JSON.parse(error.oauthError.data);
            if (errorData.message) {
              message += ` - ${errorData.message}`;
            }
          } catch (parseError) {
            message += ` - ${error.oauthError}`;
          }
        }
        reject(new Error(message));
      };
      strategy.redirect = () => {
        reject(new Error("Unexpected redirect"));
      };
      strategy.authenticate(req, { ...options ?? {} });
    });
  }
  static async executeRefreshTokenStrategy(providerStrategy, refreshToken, scope) {
    return new Promise((resolve, reject) => {
      const anyStrategy = providerStrategy;
      const OAuth2 = anyStrategy._oauth2.constructor;
      const oauth2 = new OAuth2(
        anyStrategy._oauth2._clientId,
        anyStrategy._oauth2._clientSecret,
        anyStrategy._oauth2._baseSite,
        anyStrategy._oauth2._authorizeUrl,
        anyStrategy._refreshURL || anyStrategy._oauth2._accessTokenUrl,
        anyStrategy._oauth2._customHeaders
      );
      oauth2.getOAuthAccessToken(
        refreshToken,
        {
          scope,
          grant_type: "refresh_token"
        },
        (err, accessToken, newRefreshToken, params) => {
          if (err) {
            reject(new errors.ForwardedError(`Failed to refresh access token`, err));
          }
          if (!accessToken) {
            reject(
              new Error(
                `Failed to refresh access token, no access token received`
              )
            );
          }
          resolve({
            accessToken,
            refreshToken: newRefreshToken,
            params
          });
        }
      );
    });
  }
  static async executeFetchUserProfileStrategy(providerStrategy, accessToken) {
    return new Promise((resolve, reject) => {
      const anyStrategy = providerStrategy;
      anyStrategy.userProfile(
        accessToken,
        (error, rawProfile) => {
          if (error) {
            reject(error);
          } else {
            resolve(rawProfile);
          }
        }
      );
    });
  }
}

exports.PassportHelpers = PassportHelpers;
//# sourceMappingURL=PassportHelpers.cjs.js.map
