"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UseExistingPushNotification = exports.UpdateIosPush = exports.RemoveIosPush = exports.CreateIosPush = void 0; function _chalk() { const data = _interopRequireDefault(require("chalk")); _chalk = function () { return data; }; return data; } function _get() { const data = _interopRequireDefault(require("lodash/get")); _get = 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const APPLE_KEYS_TOO_MANY_GENERATED_ERROR = ` You can have only ${_chalk().default.underline('two')} Push Notifactions Keys on your Apple Developer account. Please revoke the old ones or reuse existing from your other apps. Please remember that Apple Keys are not application specific! `; class CreateIosPush { async create(ctx) { const newPushKey = await this.provideOrGenerate(ctx); const credentials = { ...newPushKey, teamId: ctx.appleCtx.team.id, teamName: ctx.appleCtx.team.name }; return await ctx.ios.createPushKey(credentials); } async open(ctx) { const pushKey = await this.create(ctx); (0, _log().default)('Successfully created Push Notification Key\n'); (0, _list().displayIosUserCredentials)(pushKey); (0, _log().default)(); return null; } async provideOrGenerate(ctx) { const userProvided = await (0, _promptForCredentials().askForUserProvided)(_credentials().pushKeySchema); if (userProvided) { return userProvided; } return await generatePushKey(ctx); } } exports.CreateIosPush = CreateIosPush; class RemoveIosPush { constructor(shouldRevoke = false) { this.shouldRevoke = shouldRevoke; } async open(ctx) { const selected = await selectPushCredFromList(ctx.ios.credentials); if (!selected) {} else if (!(0, _get().default)(selected, 'type')) { await this.removePushCert(ctx, selected); (0, _log().default)(_chalk().default.green('Successfully removed Push Certificate')); } else { await this.removeSpecific(ctx, selected); (0, _log().default)(_chalk().default.green('Successfully removed Push Notification Key')); } return null; } async removePushCert(ctx, appCredentials) { await ctx.ios.deletePushCert(appCredentials.experienceName, appCredentials.bundleIdentifier); } async removeSpecific(ctx, selected) { const apps = getAppsUsingPushCred(ctx.ios.credentials, selected); const appsList = apps.map(appCred => appCred.experienceName).join(', '); if (appsList) { const { confirm } = await (0, _prompt().default)([{ type: 'confirm', name: 'confirm', message: `Removing this key/cert will disable notifications in ${appsList}. Do you want to continue?` }]); if (!confirm) { (0, _log().default)('Aborting'); return; } } await ctx.ios.deletePushKey(selected.id); 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().PushKeyManager)(ctx.appleCtx).revoke([selected.apnsKeyId]); } } } exports.RemoveIosPush = RemoveIosPush; class UpdateIosPush { async open(ctx) { const selected = await selectPushCredFromList(ctx.ios.credentials, false); if (selected) { await this.updateSpecific(ctx, selected); (0, _log().default)(_chalk().default.green('Successfully updated Push Notification Key.\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 = getAppsUsingPushCred(ctx.ios.credentials, selected); const appsList = apps.map(appCred => appCred.experienceName).join(', '); if (apps.length > 1) { const question = { type: 'confirm', name: 'confirm', message: `Update will affect all applications that are using this key (${appsList}). Do you want to continue?` }; const { confirm } = await (0, _prompt().default)(question); if (!confirm) { _log().default.warn('Aborting update process'); return; } } const newPushKey = await this.provideOrGenerate(ctx); const credentials = { ...newPushKey, teamId: ctx.appleCtx.team.id, teamName: ctx.appleCtx.team.name }; await ctx.ios.updatePushKey(selected.id, credentials); } async provideOrGenerate(ctx) { const userProvided = await (0, _promptForCredentials().askForUserProvided)(_credentials().pushKeySchema); if (userProvided) { return userProvided; } return await generatePushKey(ctx); } } exports.UpdateIosPush = UpdateIosPush; class UseExistingPushNotification { 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 experienceName = `@${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 filtered = ctx.ios.credentials.appCredentials.filter(app => app.experienceName === experienceName && app.bundleIdentifier === bundleIdentifier); const selected = await selectPushCredFromList(ctx.ios.credentials, false); if (selected) { await ctx.ios.usePushKey(experienceName, bundleIdentifier, selected.id); (0, _log().default)(_chalk().default.green(`Successfully assingned Push Notifactions Key to ${experienceName} (${bundleIdentifier})`)); } return null; } } exports.UseExistingPushNotification = UseExistingPushNotification; async function selectPushCredFromList(iosCredentials, allowLegacy = true) { const pushKeys = iosCredentials.userCredentials.filter(cred => cred.type === 'push-key'); const pushCerts = allowLegacy ? iosCredentials.appCredentials.filter(({ credentials }) => credentials.pushP12 && credentials.pushPassword) : []; const pushCredentials = [...pushCerts, ...pushKeys]; if (pushCredentials.length === 0) { _log().default.warn('There are no push credentials available in your account'); return null; } const getName = pushCred => { if ((0, _get().default)(pushCred, 'type') === 'push-key') { return formatPushKey(pushCred, iosCredentials); } else { const pushCert = pushCred; return `Push Certificate (PushId: ${pushCert.credentials.pushId || '------'}, TeamId: ${pushCert.credentials.teamId || '-------'} used in ${pushCert.experienceName})`; } return 'unkown credentials'; }; const question = { type: 'list', name: 'credentialsIndex', message: 'Select credentials from list', choices: pushCredentials.map((entry, index) => ({ name: getName(entry), value: index })) }; const { credentialsIndex } = await (0, _prompt().default)(question); return pushCredentials[credentialsIndex]; } function getAppsUsingPushCred(iosCredentials, pushCred) { if ((0, _get().default)(pushCred, 'type') === 'push-key') { return iosCredentials.appCredentials.filter(cred => cred.pushCredentialsId === pushCred.id); } else if ((0, _get().default)(pushCred, 'credentials.pushP12') && (0, _get().default)(pushCred, 'credentials.pushPassword')) { return [pushCred]; } return []; } function formatPushKeyFromApple(appleInfo, credentials) { const userCredentials = credentials.userCredentials.filter(cred => cred.type == 'push-key' && cred.apnsKeyId === appleInfo.id); const appCredentials = userCredentials.length !== 0 ? credentials.appCredentials.filter(cred => cred.pushCredentialsId === 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, id } = appleInfo; const pushKey = userCredentials[0]; const teamText = pushKey ? `, Team ID: ${pushKey.teamId || '---'}, Team name: ${pushKey.teamName || '---'}` : ''; return `${name} - KeyId: ${id}${teamText}\n${usedByString}`; } function formatPushKey(pushKey, credentials) { const appCredentials = credentials.appCredentials.filter(cred => cred.pushCredentialsId === pushKey.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`)}`; return `Push Notifications Key (Key ID: ${pushKey.apnsKeyId}, Team ID: ${pushKey.teamId})${usedByString}`; } async function generatePushKey(ctx) { await ctx.ensureAppleCtx(); const manager = new (_appleApi().PushKeyManager)(ctx.appleCtx); try { return await manager.create(); } catch (e) { if (e.code === 'APPLE_PUSH_KEYS_TOO_MANY_GENERATED_ERROR') { const keys = await manager.list(); _log().default.warn('Maximum number of Push Notifications Keys generated on Apple Developer Portal.'); _log().default.warn(APPLE_KEYS_TOO_MANY_GENERATED_ERROR); const usedByExpo = ctx.ios.credentials.userCredentials.filter(cert => cert.type === 'push-key').reduce((acc, cert) => ({ ...acc, [cert.apnsKeyId]: cert }), {}); const { revoke } = await (0, _prompt().default)([{ type: 'checkbox', name: 'revoke', message: 'Select Push Notifications Key to revoke.', choices: keys.map((key, index) => ({ value: index, name: formatPushKeyFromApple(key, ctx.ios.credentials) })), pageSize: Infinity }]); for (const index of revoke) { const certInfo = keys[index]; if (certInfo && usedByExpo[certInfo.id]) { await new RemoveIosPush(true).removeSpecific(ctx, usedByExpo[certInfo.id]); } else { await manager.revoke([certInfo.id]); } } } else { throw e; } } return await generatePushKey(ctx); } //# sourceMappingURL=../../__sourcemaps__/credentials/views/IosPushCredentials.js.map