"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