"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = selectDistributionCert; function _open() { const data = _interopRequireDefault(require("open")); _open = function () { return data; }; return data; } function _ora() { const data = _interopRequireDefault(require("ora")); _ora = function () { return data; }; return data; } function _xdl() { const data = require("@expo/xdl"); _xdl = function () { return data; }; return data; } function appleApi() { const data = _interopRequireWildcard(require("../build/ios/appleApi")); appleApi = function () { return data; }; return data; } function credentials() { const data = _interopRequireWildcard(require("../build/ios/credentials")); credentials = function () { return data; }; return data; } function _promptForCredentials() { const data = _interopRequireDefault(require("../build/ios/credentials/prompt/promptForCredentials")); _promptForCredentials = function () { return data; }; return data; } function _log() { const data = _interopRequireDefault(require("../../log")); _log = function () { return data; }; return data; } function _prompt() { const data = _interopRequireDefault(require("../../prompt")); _prompt = function () { return data; }; return data; } function _tagger() { const data = require("./tagger"); _tagger = function () { return data; }; return data; } function _selectUtils() { const data = require("./selectUtils"); _selectUtils = function () { return data; }; return data; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } async function selectDistributionCert(context, options = {}) { const certificates = context.username ? await chooseUnrevokedDistributionCert(context) : []; const choices = [...certificates]; // autoselect creds if we find valid ones if (certificates.length > 0 && !options.disableAutoSelectExisting) { const autoselectedCertificate = (0, _selectUtils().choosePreferredCreds)(context, certificates); (0, _log().default)(`Using Distribution Certificate: ${autoselectedCertificate.name}`); return autoselectedCertificate.value; } if (!options.disableCreate) { choices.push({ name: '[Create a new certificate] (Recommended)', value: 'GENERATE' }); } choices.push({ name: '[Upload an existing certificate]', value: 'UPLOAD' }); choices.push({ name: '[Show me more info about these choices] ℹ️', value: 'INFO' }); const { promptValue } = await (0, _prompt().default)({ type: 'list', name: 'promptValue', message: 'Select an iOS distribution certificate to use for code signing:', pageSize: Infinity, choices }); if (promptValue === 'GENERATE') { return await generateDistributionCert(context); } else if (promptValue === 'UPLOAD') { const { credentials: userProvidedCredentials, metadata } = await (0, _promptForCredentials().default)(context, ['distributionCert']); const distributionCert = userProvidedCredentials.distributionCert; distributionCert.distCertSerialNumber = metadata.distCertSerialNumber; const isValid = await validateUploadedCertificate(context, distributionCert); if (!isValid) { return await selectDistributionCert(context, { disableAutoSelectExisting: true }); } // tag for updating to Expo servers (0, _tagger().tagForUpdate)(distributionCert); } else if (promptValue === 'INFO') { (0, _open().default)('https://docs.expo.io/versions/latest/guides/adhoc-builds/#distribution-certificate-cli-options'); return await selectDistributionCert(context); } else { return promptValue; // this should be an unrevoked cert from the Expo servers } } async function validateUploadedCertificate(context, distributionCert) { const spinner = (0, _ora().default)(`Checking validity of distribution certificate on Apple Developer Portal...`).start(); const formattedDistCertArray = _xdl().Credentials.Ios.formatDistCerts([distributionCert], { provideFullCertificate: true }); const filteredFormattedDistCertArray = await filterRevokedDistributionCerts(context, formattedDistCertArray); const isValidCert = filteredFormattedDistCertArray.length > 0; if (isValidCert) { const successMsg = `Successfully validated Distribution Certificate you uploaded against Apple Servers`; spinner.succeed(successMsg); } else { const failureMsg = `The Distribution Certificate you uploaded is not valid. Please check that you uploaded your certificate to the Apple Servers. See docs.expo.io/versions/latest/guides/adhoc-builds for more details on uploading your credentials.`; spinner.fail(failureMsg); } return isValidCert; } async function chooseUnrevokedDistributionCert(context) { const certsOnExpoServer = await _xdl().Credentials.Ios.getExistingDistCerts(context.username, context.team.id, { provideFullCertificate: true }); if (certsOnExpoServer.length === 0) { return []; // no certs stored on server } const spinner = (0, _ora().default)(`Checking validity of distribution certificates on Apple Developer Portal...`).start(); const validCertsOnExpoServer = await filterRevokedDistributionCerts(context, certsOnExpoServer); const numValidCerts = validCertsOnExpoServer.length; const numRevokedCerts = certsOnExpoServer.length - validCertsOnExpoServer.length; const statusToDisplay = `Distribution Certificate: You have ${numValidCerts} valid and ${numRevokedCerts} revoked certificates on the Expo servers.`; if (numValidCerts > 0) { spinner.succeed(statusToDisplay); } else { spinner.warn(statusToDisplay); } return validCertsOnExpoServer; } async function filterRevokedDistributionCerts(context, distributionCerts) { // if the credentials are valid, check it against apple to make sure it hasnt been revoked const distCertManager = appleApi().createManagers(context).distributionCert; const certsOnAppleServer = await distCertManager.list(); const validCertSerialsOnAppleServer = certsOnAppleServer.filter( // remove expired certs cert => cert.expires > Math.floor(Date.now() / 1000)).map(cert => cert.serialNumber); const validCertsOnExpoServer = distributionCerts.filter(cert => { const serialNumber = cert.value && cert.value.distCertSerialNumber; return validCertSerialsOnAppleServer.includes(serialNumber); }); return validCertsOnExpoServer; } async function generateDistributionCert(context) { const manager = appleApi().createManagers(context).distributionCert; try { const distributionCert = await manager.create({}); // tag for updating to Expo servers (0, _tagger().tagForUpdate)(distributionCert); return distributionCert; } catch (e) { if (e.code === 'APPLE_DIST_CERTS_TOO_MANY_GENERATED_ERROR') { const certificates = await manager.list(); _log().default.warn(`Maximum number (${certificates.length}) of certificates generated.`); const { answer } = await (0, _prompt().default)({ type: 'list', name: 'answer', message: 'Please revoke or reuse an existing certificate:', choices: [{ key: 'r', name: 'Choose certificates to revoke and try again', value: 'REVOKE' }, { key: 'e', name: 'Use an existing certificate', value: 'USE_EXISTING' }, { name: '[Show me more info about these choices] ℹ️', value: 'INFO' }] }); if (answer === 'REVOKE') { await credentials().revoke(context, ['distributionCert']); return await generateDistributionCert(context); } else if (answer === 'USE_EXISTING') { return await selectDistributionCert(context, { disableCreate: true, disableAutoSelectExisting: true }); } else if (answer === 'INFO') { (0, _open().default)('https://docs.expo.io/versions/latest/guides/adhoc-builds/#distribution-certificate-cli-options'); return await generateDistributionCert(context); } } throw new Error(e); } } //# sourceMappingURL=../../__sourcemaps__/commands/client/selectDistributionCert.js.map