"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ensureCertificateValid = ensureCertificateValid;
exports.validateProvisioningProfile = validateProvisioningProfile;
exports.writeExportOptionsPlistFile = writeExportOptionsPlistFile;
exports.buildIPA = buildIPA;
exports.createEntitlementsFile = createEntitlementsFile;
exports.resignIPA = resignIPA;
Object.defineProperty(exports, "findP12CertSerialNumber", {
  enumerable: true,
  get: function () {
    return _PKCS12Utils().findP12CertSerialNumber;
  }
});
exports.resolveExportMethod = void 0;

function _lodash() {
  const data = _interopRequireDefault(require("lodash"));

  _lodash = function () {
    return data;
  };

  return data;
}

function _fsExtra() {
  const data = _interopRequireDefault(require("fs-extra"));

  _fsExtra = function () {
    return data;
  };

  return data;
}

function _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

function _globPromise() {
  const data = _interopRequireDefault(require("glob-promise"));

  _globPromise = function () {
    return data;
  };

  return data;
}

function _plist() {
  const data = _interopRequireDefault(require("plist"));

  _plist = function () {
    return data;
  };

  return data;
}

function _crypto() {
  const data = _interopRequireDefault(require("crypto"));

  _crypto = function () {
    return data;
  };

  return data;
}

function _PKCS12Utils() {
  const data = require("./PKCS12Utils");

  _PKCS12Utils = function () {
    return data;
  };

  return data;
}

function _ExponentTools() {
  const data = require("./ExponentTools");

  _ExponentTools = function () {
    return data;
  };

  return data;
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

async function ensureCertificateValid({
  certPath,
  certPassword,
  teamID
}) {
  const certData = await _fsExtra().default.readFile(certPath);
  const fingerprint = (0, _PKCS12Utils().getP12CertFingerprint)(certData, certPassword);
  const identities = await _findIdentitiesByTeamID(teamID);
  const isValid = identities.indexOf(fingerprint) !== -1;

  if (!isValid) {
    throw new Error(`codesign ident not present in find-identity: ${fingerprint}\n${identities}`);
  }

  return fingerprint;
}

async function _findIdentitiesByTeamID(teamID) {
  const {
    output
  } = await (0, _ExponentTools().spawnAsyncThrowError)('security', ['find-identity', '-v', '-s', `(${teamID})`], {
    stdio: 'pipe'
  });
  return output.join('');
}

function validateProvisioningProfile(plistData, {
  distCertFingerprint,
  bundleIdentifier
}) {
  _ensureDeveloperCertificateIsValid(plistData, distCertFingerprint);

  _ensureBundleIdentifierIsValid(plistData, bundleIdentifier);
}

function _ensureDeveloperCertificateIsValid(plistData, distCertFingerprint) {
  const devCertBase64 = plistData.DeveloperCertificates[0];

  const devCertFingerprint = _genDerCertFingerprint(devCertBase64);

  if (devCertFingerprint !== distCertFingerprint) {
    throw new Error('validateProvisioningProfile: provisioning profile is not associated with uploaded distribution certificate');
  }
}

function _genDerCertFingerprint(certBase64) {
  const certBuffer = Buffer.from(certBase64, 'base64');
  return _crypto().default.createHash('sha1').update(certBuffer).digest('hex').toUpperCase();
}

function _ensureBundleIdentifierIsValid(plistData, expectedBundleIdentifier) {
  const actualApplicationIdentifier = plistData.Entitlements['application-identifier'];
  const actualBundleIdentifier = /\.(.+)/.exec(actualApplicationIdentifier)[1];

  if (expectedBundleIdentifier !== actualBundleIdentifier) {
    throw new Error(`validateProvisioningProfile: wrong bundleIdentifier found in provisioning profile; expected: ${expectedBundleIdentifier}, found (in provisioning profile): ${actualBundleIdentifier}`);
  }
}

async function writeExportOptionsPlistFile(plistPath, data) {
  const toWrite = createExportOptionsPlist(data);
  await _fsExtra().default.writeFile(plistPath, toWrite);
}

const createExportOptionsPlist = ({
  bundleIdentifier,
  provisioningProfileUUID,
  exportMethod,
  teamID
}) => {
  const disableBitcodeCompiling = `<key>uploadBitcode</key>
    <false/>
    <key>compileBitcode</key>
    <false/>
    <key>uploadSymbols</key>
    <false/>`;
  return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>method</key>
    <string>${exportMethod}</string>
    <key>teamID</key>
    <string>${teamID}</string>
    <key>provisioningProfiles</key>
    <dict>
      <key>${bundleIdentifier}</key>
      <string>${provisioningProfileUUID}</string>
    </dict>
    ${exportMethod === 'ad-hoc' || exportMethod === 'enterprise' ? disableBitcodeCompiling : ''}
  </dict>
</plist>`;
};

async function buildIPA({
  ipaPath,
  workspacePath,
  archivePath,
  codeSignIdentity,
  exportOptionsPlistPath,
  plistData,
  keychainPath,
  exportMethod
}, credentials, client = false) {
  if (client) {
    await (0, _ExponentTools().spawnAsyncThrowError)('xcodebuild', ['-exportArchive', '-archivePath', archivePath, '-exportOptionsPlist', exportOptionsPlistPath, '-exportPath', _path().default.Dir(ipaPath), `OTHER_CODE_SIGN_FLAGS="--keychain ${keychainPath}"`], {
      env: { ...process.env,
        CI: 1
      }
    });
  } else {
    await runFastlane(credentials, ['gym', '-n', _path().default.basename(ipaPath), '--workspace', workspacePath, '--archive_path', archivePath, '--skip_build_archive', 'true', '-i', codeSignIdentity, '--export_options', exportOptionsPlistPath, '--export_method', exportMethod, '--export_xcargs', `OTHER_CODE_SIGN_FLAGS="--keychain ${keychainPath}"`, '-o', _path().default.dirname(ipaPath), '--verbose'], {
      buildPhase: 'building and signing IPA'
    });
  }
}

const resolveExportMethod = plistData => {
  if (plistData.ProvisionedDevices) {
    return 'ad-hoc';
  } else if (plistData.ProvisionsAllDevices === true) {
    return 'enterprise';
  } else {
    return 'app-store';
  }
};

exports.resolveExportMethod = resolveExportMethod;
const entitlementTransferRules = ['com.apple.developer.associated-domains', 'com.apple.developer.healthkit', 'com.apple.developer.homekit', 'com.apple.developer.icloud-container-identifiers', 'com.apple.developer.icloud-services', 'com.apple.developer.in-app-payments', 'com.apple.developer.networking.vpn.api', 'com.apple.developer.ubiquity-container-identifiers', 'com.apple.developer.ubiquity-kvstore-identifier', 'com.apple.external-accessory.wireless-configuration', 'com.apple.security.application-groups', 'inter-app-audio', 'keychain-access-groups'];
const blacklistedEntitlementKeysWithoutICloud = ['com.apple.developer.icloud-container-environment', 'com.apple.developer.icloud-container-identifiers', 'com.apple.developer.icloud-services', 'com.apple.developer.ubiquity-container-identifiers', 'com.apple.developer.ubiquity-kvstore-identifier'];
const blacklistedEntitlementKeys = ['com.apple.developer.icloud-container-development-container-identifiers', 'com.apple.developer.restricted-resource-mode', 'inter-app-audio', 'com.apple.developer.homekit', 'com.apple.developer.healthkit', 'com.apple.developer.in-app-payments', 'com.apple.developer.maps', 'com.apple.external-accessory.wireless-configuration'];
const icloudContainerEnvKey = 'com.apple.developer.icloud-container-environment';

async function createEntitlementsFile({
  generatedEntitlementsPath,
  plistData,
  archivePath,
  manifest
}) {
  const decodedProvisioningProfileEntitlements = plistData.Entitlements;

  const entitlementsPattern = _path().default.join(archivePath, 'Products/Applications/*.app/*.entitlements');

  const entitlementsPaths = await (0, _globPromise().default)(entitlementsPattern);

  if (entitlementsPaths.length === 0) {
    throw new Error("Didn't find any generated entitlements file in archive.");
  } else if (entitlementsPaths.length !== 1) {
    throw new Error('Found more than one entitlements file.');
  }

  const archiveEntitlementsPath = entitlementsPaths[0];
  const archiveEntitlementsRaw = await _fsExtra().default.readFile(archiveEntitlementsPath);

  const archiveEntitlementsData = _lodash().default.attempt(_plist().default.parse, String(archiveEntitlementsRaw));

  if (_lodash().default.isError(archiveEntitlementsData)) {
    throw new Error(`Error when parsing plist: ${archiveEntitlementsData.message}`);
  }

  const entitlements = { ...decodedProvisioningProfileEntitlements
  };
  entitlementTransferRules.forEach(rule => {
    if (rule in archiveEntitlementsData) {
      entitlements[rule] = archiveEntitlementsData[rule];
    }
  });

  let generatedEntitlements = _lodash().default.omit(entitlements, blacklistedEntitlementKeys);

  if (!manifest.ios.usesIcloudStorage) {
    generatedEntitlements = _lodash().default.omit(generatedEntitlements, blacklistedEntitlementKeysWithoutICloud);
  } else {
    const ubiquityKvKey = 'com.apple.developer.ubiquity-kvstore-identifier';

    if (generatedEntitlements[ubiquityKvKey]) {
      const teamId = generatedEntitlements[ubiquityKvKey].split('.')[0];
      generatedEntitlements[ubiquityKvKey] = `${teamId}.${manifest.ios.bundleIdentifier}`;
    }

    generatedEntitlements['com.apple.developer.icloud-services'] = ['CloudDocuments'];
  }

  if (!manifest.ios.associatedDomains) {
    generatedEntitlements = _lodash().default.omit(generatedEntitlements, 'com.apple.developer.associated-domains');
  }

  if (!manifest.ios.usesAppleSignIn) {
    generatedEntitlements = _lodash().default.omit(generatedEntitlements, 'com.apple.developer.applesignin');
  }

  if (generatedEntitlements[icloudContainerEnvKey]) {
    const envs = generatedEntitlements[icloudContainerEnvKey].filter(i => i === 'Production');
    generatedEntitlements[icloudContainerEnvKey] = envs;
  }

  const generatedEntitlementsPlistData = _lodash().default.attempt(_plist().default.build, generatedEntitlements);

  await _fsExtra().default.writeFile(generatedEntitlementsPath, generatedEntitlementsPlistData, {
    mode: 0o755
  });
  const {
    output
  } = await (0, _ExponentTools().spawnAsyncThrowError)('/usr/libexec/PlistBuddy', ['-x', '-c', 'Print', generatedEntitlementsPath], {
    stdio: 'pipe'
  });
  const plistDataReformatted = output.join('');
  await _fsExtra().default.writeFile(generatedEntitlementsPath, plistDataReformatted, {
    mode: 0o755
  });
}

async function resignIPA({
  codeSignIdentity,
  entitlementsPath,
  provisioningProfilePath,
  sourceIpaPath,
  destIpaPath,
  keychainPath
}, credentials) {
  await (0, _ExponentTools().spawnAsyncThrowError)('cp', ['-rf', sourceIpaPath, destIpaPath]);
  await runFastlane(credentials, ['sigh', 'resign', '--verbose', '--entitlements', entitlementsPath, '--signing_identity', codeSignIdentity, '--keychain_path', keychainPath, '--provisioning_profile', provisioningProfilePath, destIpaPath], {
    buildPhase: 'building and signing IPA'
  });
}

async function runFastlane({
  teamID
}, fastlaneArgs, loggerFields) {
  const fastlaneEnvVars = {
    FASTLANE_SKIP_UPDATE_CHECK: 1,
    FASTLANE_DISABLE_COLORS: 1,
    FASTLANE_TEAM_ID: teamID,
    CI: 1,
    LC_ALL: 'en_US.UTF-8'
  };
  await (0, _ExponentTools().spawnAsyncThrowError)('fastlane', fastlaneArgs, {
    env: { ...process.env,
      ...fastlaneEnvVars
    },
    pipeToLogger: true,
    dontShowStdout: false,
    loggerFields
  });
}
//# sourceMappingURL=../__sourcemaps__/detach/IosCodeSigning.js.map