text: "use strict";
  var __assign = (this && this.__assign) || function () {
      __assign = Object.assign || function(t) {
          for (var s, i = 1, n = arguments.length; i < n; i++) {
              s = arguments[i];
              for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                  t[p] = s[p];
          }
          return t;
      };
      return __assign.apply(this, arguments);
  };
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
      function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
      return new (P || (P = Promise))(function (resolve, reject) {
          function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
          function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
          function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
          step((generator = generator.apply(thisArg, _arguments || [])).next());
      });
  };
  var __generator = (this && this.__generator) || function (thisArg, body) {
      var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
      return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
      function verb(n) { return function (v) { return step([n, v]); }; }
      function step(op) {
          if (f) throw new TypeError("Generator is already executing.");
          while (_) try {
              if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
              if (y = 0, t) op = [op[0] & 2, t.value];
              switch (op[0]) {
                  case 0: case 1: t = op; break;
                  case 4: _.label++; return { value: op[1], done: false };
                  case 5: _.label++; y = op[1]; op = [0]; continue;
                  case 7: op = _.ops.pop(); _.trys.pop(); continue;
                  default:
                      if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                      if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                      if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                      if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                      if (t[2]) _.ops.pop();
                      _.trys.pop(); continue;
              }
              op = body.call(thisArg, _);
          } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
          if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
      }
  };
  var __spreadArrays = (this && this.__spreadArrays) || function () {
      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
      for (var r = Array(s), k = 0, i = 0; i < il; i++)
          for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
              r[k] = a[j];
      return r;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.buildAuthorizationHeaders = exports.basicHeader = exports.buildAndAddAuthorizationHeader = exports.getAuthHeaders = exports.addAuthorizationHeader = void 0;
  var util_1 = require("@sap-cloud-sdk/util");
  var destination_1 = require("./destination");
  var logger = util_1.createLogger({
      package: 'core',
      messageContext: 'authorization-header'
  });
  /**
   * @deprecated Since v1.20.0. Use [[buildAuthorizationHeaders]] instead.
   * Adds authorization headers for a given ODataRequest to existing headers.
   *
   * @param request - an ODataRequest.
   * @param headers - The headers that should be added to.
   * @returns The provided headers with the new authorization headers.
   */
  function addAuthorizationHeader(request, headers) {
      return __awaiter(this, void 0, void 0, function () {
          var destination, authHeaders;
          return __generator(this, function (_a) {
              switch (_a.label) {
                  case 0:
                      destination = request.destination;
                      if (!destination) {
                          return [2 /*return*/, headers];
                      }
                      return [4 /*yield*/, getAuthHeaders(destination, request.config.customHeaders)];
                  case 1:
                      authHeaders = _a.sent();
                      return [2 /*return*/, __assign(__assign({}, headers), authHeaders)];
              }
          });
      });
  }
  exports.addAuthorizationHeader = addAuthorizationHeader;
  function hasAuthHeaders(destination) {
      if (!destination.authentication) {
          return false;
      }
      var authTypesWithAuthorizationHeader = [
          'BasicAuthentication',
          'OAuth2ClientCredentials',
          'OAuth2SAMLBearerAssertion',
          'OAuth2UserTokenExchange',
          'PrincipalPropagation'
      ];
      return authTypesWithAuthorizationHeader.includes(destination.authentication);
  }
  function getAuthHeaders(destination, customHeaders) {
      return __awaiter(this, void 0, void 0, function () {
          var customAuthHeaders;
          return __generator(this, function (_a) {
              customAuthHeaders = util_1.pickIgnoreCase(customHeaders, 'authorization');
              if (Object.keys(customAuthHeaders).length && hasAuthHeaders(destination)) {
                  logger.warn('Found custom authorization headers. The given destination also provides authorization headers. This might be unintended. The custom headers from the request config will be used.');
              }
              return [2 /*return*/, Object.keys(customAuthHeaders).length
                      ? customAuthHeaders
                      : buildAuthorizationHeaders(destination)];
          });
      });
  }
  exports.getAuthHeaders = getAuthHeaders;
  /**
   * @deprecated Since v1.20.0. Use [[buildAuthorizationHeaders]] instead.
   * Adds authorization headers for a given destination to existing headers.
   *
   * @param destination - A destination.
   * @param headers - The headers that should be added to.
   * @returns The provided headers with the new authorization headers.
   */
  function buildAndAddAuthorizationHeader(destination) {
      return function (headers) {
          return __awaiter(this, void 0, void 0, function () {
              var _a;
              return __generator(this, function (_b) {
                  switch (_b.label) {
                      case 0:
                          _a = [__assign({}, headers)];
                          return [4 /*yield*/, buildAuthorizationHeaders(destination)];
                      case 1: return [2 /*return*/, __assign.apply(void 0, _a.concat([(_b.sent())]))];
                  }
              });
          });
      };
  }
  exports.buildAndAddAuthorizationHeader = buildAndAddAuthorizationHeader;
  function toAuthorizationHeader(authorization) {
      return util_1.toSanitizedObject('authorization', authorization);
  }
  function headerFromTokens(authenticationType, authTokens) {
      if (!authTokens || !authTokens.length) {
          throw Error("AuthenticationType is " + authenticationType + ", but no AuthTokens could be fetched from the destination service!");
      }
      var usableTokens = authTokens.filter(function (token) { return !token.error; });
      if (!usableTokens.length) {
          throw Error(__spreadArrays([
              'The destination tried to provide authorization tokens but failed in all cases. This is most likely due to misconfiguration.',
              'Original error messages:'
          ], authTokens.map(function (token) { return token.error; })).join('\n'));
      }
      var authToken = usableTokens[0];
      return toAuthorizationHeader(authToken.http_header.value);
  }
  function headerFromBasicAuthDestination(destination) {
      if (util_1.isNullish(destination.username) || util_1.isNullish(destination.password)) {
          throw Error('AuthenticationType is "BasicAuthentication", but "username" and / or "password" are missing!');
      }
      return toAuthorizationHeader(basicHeader(destination.username, destination.password));
  }
  function basicHeader(username, password) {
      return 'Basic ' + util_1.encodeBase64(username + ":" + password);
  }
  exports.basicHeader = basicHeader;
  function headerForPrincipalPropagation(destination) {
      var _a, _b;
      var principalPropagationHeader = (_b = (_a = destination === null || destination === void 0 ? void 0 : destination.proxyConfiguration) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b['SAP-Connectivity-Authentication'];
      if (!principalPropagationHeader) {
          throw Error('Principal propagation was selected in destination, but no SAP-Connectivity-Authentication bearer header was added by connectivity service.');
      }
      return {
          'SAP-Connectivity-Authentication': principalPropagationHeader
      };
  }
  function headerForProxy(destination) {
      var _a, _b;
      var proxyAuthHeader = (_b = (_a = destination === null || destination === void 0 ? void 0 : destination.proxyConfiguration) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b['Proxy-Authorization'];
      return proxyAuthHeader ? { 'Proxy-Authorization': proxyAuthHeader } : {};
  }
  // TODO the proxy header are for OnPrem auth and are now handled correctly and should be removed here
  // However this would be a breaking change, since we recommended to use 'NoAuthentication' to achieve principal propagation as a workaround.
  // Remove this in v2
  function legacyNoAuthOnPremiseProxy(destination) {
      logger.warn("You are using 'NoAuthentication' in destination: " + destination.name + " which is an OnPremise destination. This is a deprecated configuration, most likely you wanted to set-up 'PrincipalPropagation' so please change the destination property to the desired authentication scheme.");
      var principalPropagationHeader;
      try {
          principalPropagationHeader = headerForPrincipalPropagation(destination);
      }
      catch (e) {
          logger.warn('No principal propagation header found.');
      }
      return __assign(__assign({}, headerForProxy(destination)), principalPropagationHeader);
  }
  function getProxyRelatedAuthHeaders(destination) {
      if (destination.proxyType === 'OnPremise' &&
          destination.authentication === 'NoAuthentication') {
          return legacyNoAuthOnPremiseProxy(destination);
      }
      // The connectivity service will raise an exception if it can not obtain the 'Proxy-Authorization' and the destination lookup will fail early
      return headerForProxy(destination);
  }
  function getAuthenticationRelatedHeaders(destination) {
      return __awaiter(this, void 0, void 0, function () {
          return __generator(this, function (_a) {
              logger.debug("Getting authentication related headers for authentication type: " + destination.authentication);
              switch (destination.authentication) {
                  case null:
                  case undefined:
                      logger.warn('No authentication type is specified on the destination! Assuming "NoAuthentication".');
                      return [2 /*return*/, {}];
                  case 'NoAuthentication':
                  case 'ClientCertificateAuthentication':
                      return [2 /*return*/, {}];
                  case 'OAuth2SAMLBearerAssertion':
                  case 'OAuth2UserTokenExchange':
                  case 'OAuth2ClientCredentials':
                      return [2 /*return*/, headerFromTokens(destination.authentication, destination.authTokens)];
                  case 'BasicAuthentication':
                      return [2 /*return*/, headerFromBasicAuthDestination(destination)];
                  case 'PrincipalPropagation':
                      return [2 /*return*/, headerForPrincipalPropagation(destination)];
                  default:
                      throw Error('Failed to build authorization header for the given destination. Make sure to either correctly configure your destination for principal propagation, provide both a username and a password or select "NoAuthentication" in your destination configuration.');
              }
              return [2 /*return*/];
          });
      });
  }
  function buildAuthorizationHeaders(destination) {
      return __awaiter(this, void 0, void 0, function () {
          var sanitizedDestination, _a;
          return __generator(this, function (_b) {
              switch (_b.label) {
                  case 0:
                      sanitizedDestination = destination_1.sanitizeDestination(destination);
                      _a = [{}];
                      return [4 /*yield*/, getAuthenticationRelatedHeaders(sanitizedDestination)];
                  case 1: return [2 /*return*/, __assign.apply(void 0, [__assign.apply(void 0, _a.concat([(_b.sent())])), getProxyRelatedAuthHeaders(sanitizedDestination)])];
              }
          });
      });
  }
  exports.buildAuthorizationHeaders = buildAuthorizationHeaders;
  //# sourceMappingURL=authorization-header.js.map