"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UseExistingDistributionCert = exports.UpdateIosDist = exports.RemoveIosDist = exports.CreateIosDist = void 0; function _chalk() { const data = _interopRequireDefault(require("chalk")); _chalk = function () { return data; }; return data; } function _dateformat() { const data = _interopRequireDefault(require("dateformat")); _dateformat = function () { return data; }; return data; } function _get() { const data = _interopRequireDefault(require("lodash/get")); _get = function () { return data; }; return data; } function _xdl() { const data = require("@expo/xdl"); _xdl = function () { return data; }; return data; } function _prompt() { const data = _interopRequireDefault(require("../../prompt")); _prompt = function () { return data; }; return data; } function _log() { const data = _interopRequireDefault(require("../../log")); _log = function () { return data; }; return data; } function _credentials() { const data = require("../credentials"); _credentials = function () { return data; }; return data; } function _promptForCredentials() { const data = require("../actions/promptForCredentials"); _promptForCredentials = function () { return data; }; return data; } function _list() { const data = require("../actions/list"); _list = function () { return data; }; return data; } function _appleApi() { const data = require("../../appleApi"); _appleApi = function () { return data; }; return data; } function _IosProvisioningProfile() { const data = require("./IosProvisioningProfile"); _IosProvisioningProfile = function () { return data; }; return data; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const APPLE_DIST_CERTS_TOO_MANY_GENERATED_ERROR = ` You can have only ${_chalk().default.underline('three')} Apple Distribution Certificates generated on your Apple Developer account. Please revoke the old ones or reuse existing from your other apps. Please remember that Apple Distribution Certificates are not application specific! `; class CreateIosDist { async create(ctx) { const newDistCert = await this.provideOrGenerate(ctx); const credentials = { ...newDistCert, teamId: ctx.appleCtx.team.id, teamName: ctx.appleCtx.team.name }; return await ctx.ios.createDistCert(credentials); } async open(ctx) { const distCert = await this.create(ctx); (0, _log().default)(_chalk().default.green('Successfully created Distribution Certificate\n')); (0, _list().displayIosUserCredentials)(distCert); (0, _log().default)(); return null; } async provideOrGenerate(ctx) { const userProvided = await (0, _promptForCredentials().askForUserProvided)(_credentials().distCertSchema); if (userProvided) { return userProvided; } return await generateDistCert(ctx); } } exports.CreateIosDist = CreateIosDist; class RemoveIosDist { constructor(shouldRevoke = false) { this.shouldRevoke = shouldRevoke; } async open(ctx) { const selected = await selectDistCertFromList(ctx.ios.credentials); if (selected) { await this.removeSpecific(ctx, selected); (0, _log().default)(_chalk().default.green('Successfully removed Distribution Certificate\n')); } return null; } async removeSpecific(ctx, selected) { const apps = ctx.ios.credentials.appCredentials.filter(cred => cred.distCredentialsId === selected.id); const appsList = apps.map(appCred => _chalk().default.green(appCred.experienceName)).join(', '); if (appsList) { const { confirm } = await (0, _prompt().default)([{ type: 'confirm', name: 'confirm', message: `You are removing certificate used by ${appsList}. Do you want to continue?` }]); if (!confirm) { (0, _log().default)('Aborting'); return; } } await ctx.ios.deleteDistCert(selected.id); let shouldRevoke = false; if (selected.certId) { const { revoke } = await (0, _prompt().default)([{ type: 'confirm', name: 'revoke', message: `Do you also want to revoke it on Apple Developer Portal?`, when: !this.shouldRevoke }]); if (revoke || this.shouldRevoke) { await ctx.ensureAppleCtx(); await new (_appleApi().DistCertManager)(ctx.appleCtx).revoke([selected.certId]); } shouldRevoke = revoke; } for (const appCredentials of apps) { (0, _log().default)(`Removing Provisioning Profile for ${appCredentials.experienceName} (${appCredentials.bundleIdentifier})`); await new (_IosProvisioningProfile().RemoveProvisioningProfile)(shouldRevoke || this.shouldRevoke).removeSpecific(ctx, appCredentials); } } } exports.RemoveIosDist = RemoveIosDist; class UpdateIosDist { async open(ctx) { const selected = await selectDistCertFromList(ctx.ios.credentials); if (selected) { await this.updateSpecific(ctx, selected); (0, _log().default)(_chalk().default.green('Successfully updated Distribution Certificate\n')); const updated = ctx.ios.credentials.userCredentials.find(i => i.id === selected.id); if (updated) { (0, _list().displayIosUserCredentials)(updated); } (0, _log().default)(); } return null; } async updateSpecific(ctx, selected) { const apps = ctx.ios.credentials.appCredentials.filter(cred => cred.distCredentialsId === selected.id); const appsList = apps.map(appCred => _chalk().default.green(appCred.experienceName)).join(', '); if (apps.length > 1) { const question = { type: 'confirm', name: 'confirm', message: `You are updating cerificate used by ${appsList}. Do you want to continue?` }; const { confirm } = await (0, _prompt().default)(question); if (!confirm) { (0, _log().default)('Aborting update process'); return; } } const newDistCert = await this.provideOrGenerate(ctx); await ctx.ensureAppleCtx(); const updatedUserCredentials = await ctx.ios.updateDistCert(selected.id, { ...newDistCert, teamId: ctx.appleCtx.team.id, teamName: ctx.appleCtx.team.name }); for (const appCredentials of apps) { (0, _log().default)(`Removing Provisioning Profile for ${appCredentials.experienceName} (${appCredentials.bundleIdentifier})`); await new (_IosProvisioningProfile().RemoveProvisioningProfile)(true).removeSpecific(ctx, appCredentials); } } async provideOrGenerate(ctx) { const userProvided = await (0, _promptForCredentials().askForUserProvided)(_credentials().distCertSchema); if (userProvided) { return userProvided; } return await generateDistCert(ctx); } } exports.UpdateIosDist = UpdateIosDist; class UseExistingDistributionCert { async open(ctx) { if (!ctx.hasProjectContext) { _log().default.error('Can only be used in project context'); return null; } const experience = (0, _get().default)(ctx, 'manifest.slug'); const owner = (0, _get().default)(ctx, 'manifest.owner'); const experienceName = `@${owner || ctx.user.username}/${experience}`; const bundleIdentifier = (0, _get().default)(ctx, 'manifest.ios.bundleIdentifier'); if (!experience || !bundleIdentifier) { _log().default.error(`slug and ios.bundleIdentifier needs to be defined`); return null; } const selected = await selectDistCertFromList(ctx.ios.credentials); if (selected) { await ctx.ios.useDistCert(experienceName, bundleIdentifier, selected.id); (0, _log().default)(_chalk().default.green(`Successfully assingned Distribution Certificate to ${experienceName} (${bundleIdentifier})`)); } return null; } } exports.UseExistingDistributionCert = UseExistingDistributionCert; async function selectDistCertFromList(iosCredentials) { const distCerts = iosCredentials.userCredentials.filter(cred => cred.type === 'dist-cert'); if (distCerts.length === 0) { _log().default.warn('There are no Distribution Certificates available in your expo account'); return null; } const question = { type: 'list', name: 'credentialsIndex', message: 'Select certificate from the list.', choices: distCerts.map((entry, index) => ({ name: formatDistCert(entry, iosCredentials), value: index })) }; const { credentialsIndex } = await (0, _prompt().default)(question); return distCerts[credentialsIndex]; } function formatDistCertFromApple(appleInfo, credentials) { const userCredentials = credentials.userCredentials.filter(cred => cred.type == 'dist-cert' && cred.certId === appleInfo.id); const appCredentials = userCredentials.length !== 0 ? credentials.appCredentials.filter(cred => cred.distCredentialsId === userCredentials[0].id) : []; const joinApps = appCredentials.map(i => ` ${i.experienceName} (${i.bundleIdentifier})`).join('\n'); const usedByString = !!joinApps ? ` ${_chalk().default.gray(`used by\n${joinApps}`)}` : ` ${_chalk().default.gray(`not used by any apps`)}`; const { name, status, id, expires, created, ownerName, serialNumber } = appleInfo; const expiresDate = (0, _dateformat().default)(new Date(expires * 1000)); const createdDate = (0, _dateformat().default)(new Date(created * 1000)); return `${name} (${status}) - Cert ID: ${id}, Serial number: ${serialNumber}, Team ID: ${appleInfo.ownerId}, Team name: ${ownerName} expires: ${expiresDate}, created: ${createdDate} ${usedByString}`; } function formatDistCert(distCert, credentials) { const appCredentials = credentials.appCredentials.filter(cred => cred.distCredentialsId === distCert.id); const joinApps = appCredentials.map(i => `${i.experienceName} (${i.bundleIdentifier})`).join(', '); const usedByString = !!joinApps ? `\n ${_chalk().default.gray(`used by ${joinApps}`)}` : `\n ${_chalk().default.gray(`not used by any apps`)}`; let serialNumber = distCert.distCertSerialNumber; try { if (!serialNumber) { serialNumber = _xdl().IosCodeSigning.findP12CertSerialNumber(distCert.certP12, distCert.certPassword); } } catch (error) { serialNumber = _chalk().default.red('invalid serial number'); } return `Distribution Certificate (Cert ID: ${distCert.certId}, Serial number: ${serialNumber}, Team ID: ${distCert.teamId})${usedByString}`; } async function generateDistCert(ctx) { await ctx.ensureAppleCtx(); const manager = new (_appleApi().DistCertManager)(ctx.appleCtx); try { return await manager.create(); } catch (e) { if (e.code === 'APPLE_DIST_CERTS_TOO_MANY_GENERATED_ERROR') { const certs = await manager.list(); _log().default.warn('Maximum number of Distribution Certificates generated on Apple Developer Portal.'); _log().default.warn(APPLE_DIST_CERTS_TOO_MANY_GENERATED_ERROR); const usedByExpo = ctx.ios.credentials.userCredentials.filter(cert => cert.type === 'dist-cert' && !!cert.certId).reduce((acc, cert) => ({ ...acc, [cert.certId || '']: cert }), {}); const { revoke } = await (0, _prompt().default)([{ type: 'checkbox', name: 'revoke', message: 'Select certificates to revoke.', choices: certs.map((cert, index) => ({ value: index, name: formatDistCertFromApple(cert, ctx.ios.credentials) })), pageSize: Infinity }]); for (const index of revoke) { const certInfo = certs[index]; if (certInfo && usedByExpo[certInfo.id]) { await new RemoveIosDist(true).removeSpecific(ctx, usedByExpo[certInfo.id]); } else { await manager.revoke([certInfo.id]); } } } else { throw e; } } return await generateDistCert(ctx); } //# sourceMappingURL=../../__sourcemaps__/credentials/views/IosDistCert.js.map