} instance.
   */
  static create(options) {
    return new DefaultIdentityClient(options);
  }
  async getIdentity(options) {
    const {
      request: { headers }
    } = options;
    if (!headers.authorization) {
      return void 0;
    }
    try {
      return await this.authenticate(
        getBearerTokenFromAuthorizationHeader(headers.authorization)
      );
    } catch (e) {
      throw new errors.AuthenticationError(e.message);
    }
  }
  /**
   * Verifies the given backstage identity token
   * Returns a BackstageIdentity (user) matching the token.
   * The method throws an error if verification fails.
   *
   * @deprecated You should start to use getIdentity instead of authenticate to retrieve the user
   * identity.
   */
  async authenticate(token) {
    if (!token) {
      throw new errors.AuthenticationError("No token specified");
    }
    await this.refreshKeyStore(token);
    if (!this.keyStore) {
      throw new errors.AuthenticationError("No keystore exists");
    }
    const decoded = await jose.jwtVerify(token, this.keyStore, {
      algorithms: this.algorithms,
      audience: "backstage",
      issuer: this.issuer
    });
    if (!decoded.payload.sub) {
      throw new errors.AuthenticationError("No user sub found in token");
    }
    const user = {
      token,
      identity: {
        type: "user",
        userEntityRef: decoded.payload.sub,
        ownershipEntityRefs: decoded.payload.ent ? decoded.payload.ent : []
      }
    };
    return user;
  }
  /**
   * If the last keystore refresh is stale, update the keystore URL to the latest
   */
  async refreshKeyStore(rawJwtToken) {
    const payload = await jose.decodeJwt(rawJwtToken);
    const header = await jose.decodeProtectedHeader(rawJwtToken);
    let keyStoreHasKey;
    try {
      if (this.keyStore) {
        const [_, rawPayload, rawSignature] = rawJwtToken.split(".");
        keyStoreHasKey = await this.keyStore(header, {
          payload: rawPayload,
          signature: rawSignature
        });
      }
    } catch (error) {
      keyStoreHasKey = false;
    }
    const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > this.keyStoreUpdated - CLOCK_MARGIN_S;
    if (!this.keyStore || !keyStoreHasKey && issuedAfterLastRefresh) {
      const url = await this.discovery.getBaseUrl("auth");
      const endpoint = new URL(`${url}/.well-known/jwks.json`);
      this.keyStore = jose.createRemoteJWKSet(endpoint);
      this.keyStoreUpdated = Date.now() / 1e3;
    }
  }
}

var __defProp$3 = Object.defineProperty;
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField$3 = (obj, key, value) => {
  __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
class IdentityClient {
  constructor(defaultIdentityClient) {
    __publicField$3(this, "defaultIdentityClient");
    this.defaultIdentityClient = defaultIdentityClient;
  }
  static create(options) {
    return new IdentityClient(DefaultIdentityClient.create(options));
  }
  /**
   * Verifies the given backstage identity token
   * Returns a BackstageIdentity (user) matching the token.
   * The method throws an error if verification fails.
   *
   * @deprecated You should start to use IdentityApi#getIdentity instead of authenticate
   * to retrieve the user identity.
   */
  async authenticate(token) {
    return await this.defaultIdentityClient.authenticate(token);
  }
}

function encodeOAuthState(state) {
  const stateString = new URLSearchParams(
    pickBy__default["default"](state, (value) => value !== void 0)
  ).toString();
  return Buffer.from(stateString, "utf-8").toString("hex");
}
function decodeOAuthState(encodedState) {
  var _a, _b;
  const state = Object.fromEntries(
    new URLSearchParams(Buffer.from(encodedState, "hex").toString("utf-8"))
  );
  if (!state.env || ((_a = state.env) == null ? void 0 : _a.length) === 0) {
    throw new errors.NotAllowedError("OAuth state is invalid, missing env");
  }
  if (!state.nonce || ((_b = state.nonce) == null ? void 0 : _b.length) === 0) {
    throw new errors.NotAllowedError("OAuth state is invalid, missing nonce");
  }
  return state;
}

var __defProp$2 = Object.defineProperty;
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField$2 = (obj, key, value) => {
  __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
const THOUSAND_DAYS_MS = 1e3 * 24 * 60 * 60 * 1e3;
const TEN_MINUTES_MS = 600 * 1e3;
const defaultCookieConfigurer = ({
  callbackUrl,
  providerId,
  appOrigin
}) => {
  const { hostname: domain, pathname, protocol } = new URL(callbackUrl);
  const secure = protocol === "https:";
  let sameSite = "lax";
  if (new URL(appOrigin).hostname !== domain && secure) {
    sameSite = "none";
  }
  const path = pathname.endsWith(`${providerId}/handler/frame`) ? pathname.slice(0, -"/handler/frame".length) : `${pathname}/${providerId}`;
  return { domain, path, secure, sameSite };
};
class OAuthCookieManager {
  constructor(options) {
    this.options = options;
    __publicField$2(this, "cookieConfigurer");
    __publicField$2(this, "nonceCookie");
    __publicField$2(this, "refreshTokenCookie");
    __publicField$2(this, "grantedScopeCookie");
    var _a;
    this.cookieConfigurer = (_a = options.cookieConfigurer) != null ? _a : defaultCookieConfigurer;
    this.nonceCookie = `${options.providerId}-nonce`;
    this.refreshTokenCookie = `${options.providerId}-refresh-token`;
    this.grantedScopeCookie = `${options.providerId}-granted-scope`;
  }
  getConfig(origin, pathSuffix = "") {
    const cookieConfig = this.cookieConfigurer({
      providerId: this.options.providerId,
      baseUrl: this.options.baseUrl,
      callbackUrl: this.options.callbackUrl,
      appOrigin: origin != null ? origin : this.options.defaultAppOrigin
    });
    return {
      httpOnly: true,
      sameSite: "lax",
      ...cookieConfig,
      path: cookieConfig.path + pathSuffix
    };
  }
  setNonce(res, nonce, origin) {
    res.cookie(this.nonceCookie, nonce, {
      maxAge: TEN_MINUTES_MS,
      ...this.getConfig(origin, "/handler")
    });
  }
  setRefreshToken(res, refreshToken, origin) {
    res.cookie(this.refreshTokenCookie, refreshToken, {
      maxAge: THOUSAND_DAYS_MS,
      ...this.getConfig(origin)
    });
  }
  removeRefreshToken(res, origin) {
    res.cookie(this.refreshTokenCookie, "", {
      maxAge: 0,
      ...this.getConfig(origin)
    });
  }
  setGrantedScopes(res, scope, origin) {
    res.cookie(this.grantedScopeCookie, scope, {
      maxAge: THOUSAND_DAYS_MS,
      ...this.getConfig(origin)
    });
  }
  getNonce(req) {
    return req.cookies[this.nonceCookie];
  }
  getRefreshToken(req) {
    return req.cookies[this.refreshTokenCookie];
  }
  getGrantedScopes(req) {
    return req.cookies[this.grantedScopeCookie];
  }
}

function createOAuthRouteHandlers(options) {
  var _a, _b, _c;
  const {
    authenticator,
    config,
    baseUrl,
    appUrl,
    providerId,
    isOriginAllowed,
    cookieConfigurer,
    resolverContext,
    signInResolver
  } = options;
  const defaultAppOrigin = new url.URL(appUrl).origin;
  const callbackUrl = (_a = config.getOptionalString("callbackUrl")) != null ? _a : `${baseUrl}/${providerId}/handler/frame`;
  const stateTransform = (_b = options.stateTransform) != null ? _b : (state) => ({ state });
  const profileTransform = (_c = options.profileTransform) != null ? _c : authenticator.defaultProfileTransform;
  const authenticatorCtx = authenticator.initialize({ config, callbackUrl });
  const cookieManager = new OAuthCookieManager({
    baseUrl,
    callbackUrl,
    defaultAppOrigin,
    providerId,
    cookieConfigurer
  });
  return {
    async start(req, res) {
      var _a2, _b2, _c2, _d, _e, _f;
      const scope = (_b2 = (_a2 = req.query.scope) == null ? void 0 : _a2.toString()) != null ? _b2 : "";
      const env = (_c2 = req.query.env) == null ? void 0 : _c2.toString();
      const origin = (_d = req.query.origin) == null ? void 0 : _d.toString();
      const redirectUrl = (_e = req.query.redirectUrl) == null ? void 0 : _e.toString();
      const flow = (_f = req.query.flow) == null ? void 0 : _f.toString();
      if (!env) {
        throw new errors.InputError("No env provided in request query parameters");
      }
      const nonce = crypto__default["default"].randomBytes(16).toString("base64");
      cookieManager.setNonce(res, nonce, origin);
      const state = { nonce, env, origin, redirectUrl, flow };
      if (authenticator.shouldPersistScopes && scope) {
        state.scope = scope;
      }
      const { state: transformedState } = await stateTransform(state, { req });
      const encodedState = encodeOAuthState(transformedState);
      const { url, status } = await options.authenticator.start(
        { req, scope, state: encodedState },
        authenticatorCtx
      );
      res.statusCode = status || 302;
      res.setHeader("Location", url);
      res.setHeader("Content-Length", "0");
      res.end();
    },
    async frameHandler(req, res) {
      var _a2, _b2;
      let appOrigin = defaultAppOrigin;
      try {
        const state = decodeOAuthState((_b2 = (_a2 = req.query.state) == null ? void 0 : _a2.toString()) != null ? _b2 : "");
        if (state.origin) {
          try {
            appOrigin = new url.URL(state.origin).origin;
          } catch {
            throw new errors.NotAllowedError("App origin is invalid, failed to parse");
          }
          if (!isOriginAllowed(appOrigin)) {
            throw new errors.NotAllowedError(`Origin '${appOrigin}' is not allowed`);
          }
        }
        const cookieNonce = cookieManager.getNonce(req);
        const stateNonce = state.nonce;
        if (!cookieNonce) {
          throw new errors.NotAllowedError("Auth response is missing cookie nonce");
        }
        if (cookieNonce !== stateNonce) {
          throw new errors.NotAllowedError("Invalid nonce");
        }
        const result = await authenticator.authenticate(
          { req },
          authenticatorCtx
        );
        const { profile } = await profileTransform(result, resolverContext);
        const response = {
          profile,
          providerInfo: {
            idToken: result.session.idToken,
            accessToken: result.session.accessToken,
            scope: result.session.scope,
            expiresInSeconds: result.session.expiresInSeconds
          }
        };
        if (signInResolver) {
          const identity = await signInResolver(
            { profile, result },
            resolverContext
          );
          response.backstageIdentity = prepareBackstageIdentityResponse(identity);
        }
        if (authenticator.shouldPersistScopes && state.scope) {
          cookieManager.setGrantedScopes(res, state.scope, appOrigin);
          response.providerInfo.scope = state.scope;
        }
        if (result.session.refreshToken) {
          cookieManager.setRefreshToken(
            res,
            result.session.refreshToken,
            appOrigin
          );
        }
        if (state.flow === "redirect") {
          if (!state.redirectUrl) {
            throw new errors.InputError(
              "No redirectUrl provided in request query parameters"
            );
          }
          res.redirect(state.redirectUrl);
          return;
        }
        sendWebMessageResponse(res, appOrigin, {
          type: "authorization_response",
          response
        });
      } catch (error) {
        const { name, message } = errors.isError(error) ? error : new Error("Encountered invalid error");
        sendWebMessageResponse(res, appOrigin, {
          type: "authorization_response",
          error: { name, message }
        });
      }
    },
    async logout(req, res) {
      if (req.header("X-Requested-With") !== "XMLHttpRequest") {
        throw new errors.AuthenticationError("Invalid X-Requested-With header");
      }
      if (authenticator.logout) {
        const refreshToken = cookieManager.getRefreshToken(req);
        await authenticator.logout({ req, refreshToken }, authenticatorCtx);
      }
      cookieManager.removeRefreshToken(res, req.get("origin"));
      res.status(200).end();
    },
    async refresh(req, res) {
      var _a2, _b2;
      if (req.header("X-Requested-With") !== "XMLHttpRequest") {
        throw new errors.AuthenticationError("Invalid X-Requested-With header");
      }
      try {
        const refreshToken = cookieManager.getRefreshToken(req);
        if (!refreshToken) {
          throw new errors.InputError("Missing session cookie");
        }
        let scope = (_b2 = (_a2 = req.query.scope) == null ? void 0 : _a2.toString()) != null ? _b2 : "";
        if (authenticator.shouldPersistScopes) {
          scope = cookieManager.getGrantedScopes(req);
        }
        const result = await authenticator.refresh(
          { req, scope, refreshToken },
          authenticatorCtx
        );
        const { profile } = await profileTransform(result, resolverContext);
        const newRefreshToken = result.session.refreshToken;
        if (newRefreshToken && newRefreshToken !== refreshToken) {
          cookieManager.setRefreshToken(
            res,
            newRefreshToken,
            req.get("origin")
          );
        }
        const response = {
          profile,
          providerInfo: {
            idToken: result.session.idToken,
            accessToken: result.session.accessToken,
            scope: authenticator.shouldPersistScopes ? scope : result.session.scope,
            expiresInSeconds: result.session.expiresInSeconds
          }
        };
        if (signInResolver) {
          const identity = await signInResolver(
            { profile, result },
            resolverContext
          );
          response.backstageIdentity = prepareBackstageIdentityResponse(identity);
        }
        res.status(200).json(response);
      } catch (error) {
        throw new errors.AuthenticationError("Refresh failed", error);
      }
    }
  };
}

var __defProp$1 = Object.defineProperty;
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField$1 = (obj, key, value) => {
  __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
function decodeJwtPayload(token) {
  const payloadStr = token.split(".")[1];
  if (!payloadStr) {
    throw new Error("Invalid JWT token");
  }
  let payload;
  try {
    payload = JSON.parse(
      Buffer.from(
        payloadStr.replace(/-/g, "+").replace(/_/g, "/"),
        "base64"
      ).toString("utf8")
    );
  } catch (e) {
    throw new Error("Invalid JWT token");
  }
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
    throw new Error("Invalid JWT token");
  }
  return payload;
}
class PassportHelpers {
  constructor() {
  }
  static async executeRedirectStrategy(req, providerStrategy, options) {
    return new Promise((resolve) => {
      const strategy = Object.create(providerStrategy);
      strategy.redirect = (url, status) => {
        resolve({ url, status: status != null ? 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) => {
        var _a;
        reject(new Error(`Authentication rejected, ${(_a = info.message) != null ? _a : ""}`));
      };
      strategy.error = (error) => {
        var _a;
        let message = `Authentication failed, ${error.message}`;
        if ((_a = error.oauthError) == null ? void 0 : _a.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 != null ? 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 Error(`Failed to refresh access token ${err.toString()}`)
            );
          }
          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);
          }
        }
      );
    });
  }
}
__publicField$1(PassportHelpers, "transformProfile", (profile, idToken) => {
  var _a, _b;
  let email = void 0;
  if (profile.emails && profile.emails.length > 0) {
    const [firstEmail] = profile.emails;
    email = firstEmail.value;
  }
  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;
  }
  let displayName = (_b = (_a = profile.displayName) != null ? _a : profile.username) != null ? _b : profile.id;
  if ((!email || !picture || !displayName) && idToken) {
    try {
      const decoded = decodeJwtPayload(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 Error(`Failed to parse id token and get profile info, ${e}`);
    }
  }
  return {
    email,
    picture,
    displayName
  };
});

var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
var __accessCheck = (obj, member, msg) => {
  if (!member.has(obj))
    throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
  __accessCheck(obj, member, "read from private field");
  return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
  if (member.has(obj))
    throw TypeError("Cannot add the same private member more than once");
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
  __accessCheck(obj, member, "write to private field");
  setter ? setter.call(obj, value) : member.set(obj, value);
  return value;
};
var _strategy;
const _PassportOAuthAuthenticatorHelper = class _PassportOAuthAuthenticatorHelper {
  constructor(strategy) {
    __privateAdd(this, _strategy, void 0);
    __privateSet(this, _strategy, strategy);
  }
  static from(strategy) {
    return new _PassportOAuthAuthenticatorHelper(strategy);
  }
  async start(input, options) {
    return PassportHelpers.executeRedirectStrategy(input.req, __privateGet(this, _strategy), {
      scope: input.scope,
      state: input.state,
      ...options
    });
  }
  async authenticate(input) {
    var _a;
    const { result, privateInfo } = await PassportHelpers.executeFrameHandlerStrategy(input.req, __privateGet(this, _strategy));
    return {
      fullProfile: result.fullProfile,
      session: {
        accessToken: result.accessToken,
        tokenType: (_a = result.params.token_type) != null ? _a : "bearer",
        scope: result.params.scope,
        expiresInSeconds: result.params.expires_in,
        idToken: result.params.id_token,
        refreshToken: privateInfo.refreshToken
      }
    };
  }
  async refresh(input) {
    var _a;
    const result = await PassportHelpers.executeRefreshTokenStrategy(
      __privateGet(this, _strategy),
      input.refreshToken,
      input.scope
    );
    const fullProfile = await this.fetchProfile(result.accessToken);
    return {
      fullProfile,
      session: {
        accessToken: result.accessToken,
        tokenType: (_a = result.params.token_type) != null ? _a : "bearer",
        scope: result.params.scope,
        expiresInSeconds: result.params.expires_in,
        idToken: result.params.id_token,
        refreshToken: result.refreshToken
      }
    };
  }
  async fetchProfile(accessToken) {
    const profile = await PassportHelpers.executeFetchUserProfileStrategy(
      __privateGet(this, _strategy),
      accessToken
    );
    return profile;
  }
};
_strategy = new WeakMap();
__publicField(_PassportOAuthAuthenticatorHelper, "defaultProfileTransform", async (input) => ({
  profile: PassportHelpers.transformProfile(
    input.fullProfile,
    input.session.idToken
  )
}));
let PassportOAuthAuthenticatorHelper = _PassportOAuthAuthenticatorHelper;

class OAuthEnvironmentHandler {
  constructor(handlers) {
    this.handlers = handlers;
  }
  static mapConfig(config, factoryFunc) {
    const envs = config.keys();
    const handlers = /* @__PURE__ */ new Map();
    for (const env of envs) {
      const envConfig = config.getConfig(env);
      const handler = factoryFunc(envConfig);
      handlers.set(env, handler);
    }
    return new OAuthEnvironmentHandler(handlers);
  }
  async start(req, res) {
    const provider = this.getProviderForEnv(req);
    await provider.start(req, res);
  }
  async frameHandler(req, res) {
    const provider = this.getProviderForEnv(req);
    await provider.frameHandler(req, res);
  }
  async refresh(req, res) {
    var _a;
    const provider = this.getProviderForEnv(req);
    await ((_a = provider.refresh) == null ? void 0 : _a.call(provider, req, res));
  }
  async logout(req, res) {
    var _a;
    const provider = this.getProviderForEnv(req);
    await ((_a = provider.logout) == null ? void 0 : _a.call(provider, req, res));
  }
  getEnvFromRequest(req) {
    var _a, _b;
    const reqEnv = (_a = req.query.env) == null ? void 0 : _a.toString();
    if (reqEnv) {
      return reqEnv;
    }
    const stateParams = (_b = req.query.state) == null ? void 0 : _b.toString();
    if (!stateParams) {
      return void 0;
    }
    const { env } = decodeOAuthState(stateParams);
    return env;
  }
  getProviderForEnv(req) {
    const env = this.getEnvFromRequest(req);
    if (!env) {
      throw new errors.InputError(`Must specify 'env' query to select environment`);
    }
    const handler = this.handlers.get(env);
    if (!handler) {
      throw new errors.NotFoundError(
        `No configuration available for the '${env}' environment of this provider.`
      );
    }
    return handler;
  }
}

function createSignInResolverFactory(options) {
  const { optionsSchema } = options;
  if (!optionsSchema) {
    return (resolverOptions) => {
      if (resolverOptions) {
        throw new errors.InputError("sign-in resolver does not accept options");
      }
      return options.create(void 0);
    };
  }
  const factory = (...[resolverOptions]) => {
    const parsedOptions = optionsSchema.parse(resolverOptions);
    return options.create(parsedOptions);
  };
  factory.optionsJsonSchema = zodToJsonSchema__default["default"](optionsSchema);
  return factory;
}

function readDeclarativeSignInResolver(options) {
  var _a, _b;
  const resolvers = (_b = (_a = options.config.getOptionalConfigArray("signIn.resolvers")) == null ? void 0 : _a.map((resolverConfig) => {
    const resolverName = resolverConfig.getString("resolver");
    if (!Object.hasOwn(options.signInResolverFactories, resolverName)) {
      throw new Error(
        `Sign-in resolver '${resolverName}' is not available`
      );
    }
    const resolver = options.signInResolverFactories[resolverName];
    const { resolver: _ignored, ...resolverOptions } = resolverConfig.get();
    return resolver(
      Object.keys(resolverOptions).length > 0 ? resolverOptions : void 0
    );
  })) != null ? _b : [];
  if (resolvers.length === 0) {
    return void 0;
  }
  return async (profile, context) => {
    for (const resolver of resolvers) {
      try {
        return await resolver(profile, context);
      } catch (error) {
        if ((error == null ? void 0 : error.name) === "NotFoundError") {
          continue;
        }
        throw error;
      }
    }
    throw new Error("Failed to sign-in, unable to resolve user identity");
  };
}

exports.commonSignInResolvers = void 0;
((commonSignInResolvers2) => {
  commonSignInResolvers2.emailMatchingUserEntityProfileEmail = createSignInResolverFactory({
    create() {
      return async (info, ctx) => {
        const { profile } = info;
        if (!profile.email) {
          throw new Error(
            "Login failed, user profile does not contain an email"
          );
        }
        return ctx.signInWithCatalogUser({
          filter: {
            "spec.profile.email": profile.email
          }
        });
      };
    }
  });
  commonSignInResolvers2.emailLocalPartMatchingUserEntityName = createSignInResolverFactory({
    create() {
      return async (info, ctx) => {
        const { profile } = info;
        if (!profile.email) {
          throw new Error(
            "Login failed, user profile does not contain an email"
          );
        }
        const [localPart] = profile.email.split("@");
        return ctx.signInWithCatalogUser({
          entityRef: { name: localPart }
        });
      };
    }
  });
})(exports.commonSignInResolvers || (exports.commonSignInResolvers = {}));

function createOAuthProviderFactory(options) {
  return (ctx) => {
    return OAuthEnvironmentHandler.mapConfig(ctx.config, (envConfig) => {
      var _a, _b;
      const signInResolver = (_b = options.signInResolver) != null ? _b : readDeclarativeSignInResolver({
        config: envConfig,
        signInResolverFactories: (_a = options.signInResolverFactories) != null ? _a : {}
      });
      return createOAuthRouteHandlers({
        authenticator: options.authenticator,
        appUrl: ctx.appUrl,
        baseUrl: ctx.baseUrl,
        config: envConfig,
        isOriginAllowed: ctx.isOriginAllowed,
        cookieConfigurer: ctx.cookieConfigurer,
        providerId: ctx.providerId,
        resolverContext: ctx.resolverContext,
        stateTransform: options.stateTransform,
        profileTransform: options.profileTransform,
        signInResolver
      });
    });
  };
}

function createOAuthAuthenticator(authenticator) {
  return authenticator;
}

function createProxyAuthenticator(authenticator) {
  return authenticator;
}

function createProxyAuthRouteHandlers(options) {
  var _a;
  const { authenticator, config, resolverContext, signInResolver } = options;
  const profileTransform = (_a = options.profileTransform) != null ? _a : authenticator.defaultProfileTransform;
  const authenticatorCtx = authenticator.initialize({ config });
  return {
    async start() {
      throw new errors.NotImplementedError("Not implemented");
    },
    async frameHandler() {
      throw new errors.NotImplementedError("Not implemented");
    },
    async refresh(req, res) {
      const { result } = await authenticator.authenticate(
        { req },
        authenticatorCtx
      );
      const { profile } = await profileTransform(result, resolverContext);
      const identity = await signInResolver(
        { profile, result },
        resolverContext
      );
      const response = {
        profile,
        providerInfo: {},
        backstageIdentity: prepareBackstageIdentityResponse(identity)
      };
      res.status(200).json(response);
    }
  };
}

function createProxyAuthProviderFactory(options) {
  return (ctx) => {
    var _a, _b;
    const signInResolver = (_b = options.signInResolver) != null ? _b : readDeclarativeSignInResolver({
      config: ctx.config,
      signInResolverFactories: (_a = options.signInResolverFactories) != null ? _a : {}
    });
    if (!signInResolver) {
      throw new Error(
        `No sign-in resolver configured for proxy auth provider '${ctx.providerId}'`
      );
    }
    return createProxyAuthRouteHandlers({
      signInResolver,
      config: ctx.config,
      authenticator: options.authenticator,
      resolverContext: ctx.resolverContext,
      profileTransform: options.profileTransform
    });
  };
}

exports.DefaultIdentityClient = DefaultIdentityClient;
exports.IdentityClient = IdentityClient;
exports.OAuthEnvironmentHandler = OAuthEnvironmentHandler;
exports.PassportHelpers = PassportHelpers;
exports.PassportOAuthAuthenticatorHelper = PassportOAuthAuthenticatorHelper;
exports.authProvidersExtensionPoint = authProvidersExtensionPoint;
exports.createOAuthAuthenticator = createOAuthAuthenticator;
exports.createOAuthProviderFactory = createOAuthProviderFactory;
exports.createOAuthRouteHandlers = createOAuthRouteHandlers;
exports.createProxyAuthProviderFactory = createProxyAuthProviderFactory;
exports.createProxyAuthRouteHandlers = createProxyAuthRouteHandlers;
exports.createProxyAuthenticator = createProxyAuthenticator;
exports.createSignInResolverFactory = createSignInResolverFactory;
exports.decodeOAuthState = decodeOAuthState;
exports.encodeOAuthState = encodeOAuthState;
exports.getBearerTokenFromAuthorizationHeader = getBearerTokenFromAuthorizationHeader;
exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
exports.readDeclarativeSignInResolver = readDeclarativeSignInResolver;
exports.sendWebMessageResponse = sendWebMessageResponse;
//# sourceMappingURL=index.cjs.js.map
