"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