"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = _default;

function _fsExtra() {
  const data = _interopRequireDefault(require("fs-extra"));

  _fsExtra = function () {
    return data;
  };

  return data;
}

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function () {
    return data;
  };

  return data;
}

function _xdl() {
  const data = require("@expo/xdl");

  _xdl = function () {
    return data;
  };

  return data;
}

function ConfigUtils() {
  const data = _interopRequireWildcard(require("@expo/config"));

  ConfigUtils = function () {
    return data;
  };

  return data;
}

function _log() {
  const data = _interopRequireDefault(require("../log"));

  _log = 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 }; }

function _default(program) {
  program.command('push:android:upload [project-dir]').description('Uploads a Firebase Cloud Messaging key for Android push notifications.').option('--api-key [api-key]', 'Server API key for FCM.').asyncActionProjectDir(async (projectDir, options) => {
    if (!options.apiKey || options.apiKey.length === 0) {
      throw new Error('Must specify an API key to upload with --api-key.');
    }

    (0, _log().default)('Reading project configuration...');
    const {
      args: {
        remotePackageName
      }
    } = await _xdl().Exp.getPublishInfoAsync(projectDir);
    (0, _log().default)('Logging in...');
    let user = await _xdl().UserManager.getCurrentUserAsync();

    let apiClient = _xdl().ApiV2.clientForUser(user);

    (0, _log().default)("Setting API key on Expo's servers...");
    await apiClient.putAsync(`credentials/push/android/${remotePackageName}`, {
      fcmApiKey: options.apiKey
    });
    (0, _log().default)('All done!');
  }, true);
  program.command('push:android:show [project-dir]').description('Print the value currently in use for FCM notifications for this project.').asyncActionProjectDir(async projectDir => {
    const {
      args: {
        remotePackageName
      }
    } = await _xdl().Exp.getPublishInfoAsync(projectDir);
    let user = await _xdl().UserManager.getCurrentUserAsync();

    let apiClient = _xdl().ApiV2.clientForUser(user);

    let result = await apiClient.getAsync(`credentials/push/android/${remotePackageName}`);

    if (result.status === 'ok' && result.fcmApiKey) {
      console.log(JSON.stringify(result));
    } else {
      throw new Error('Server returned an invalid result!');
    }
  }, true);
  program.command('push:android:clear [project-dir]').description('Deletes a previously uploaded FCM credential.').asyncActionProjectDir(async projectDir => {
    (0, _log().default)('Reading project configuration...');
    const {
      args: {
        remotePackageName
      }
    } = await _xdl().Exp.getPublishInfoAsync(projectDir);
    (0, _log().default)('Logging in...');
    let user = await _xdl().UserManager.getCurrentUserAsync();

    let apiClient = _xdl().ApiV2.clientForUser(user);

    (0, _log().default)("Deleting API key from Expo's servers...");
    await apiClient.deleteAsync(`credentials/push/android/${remotePackageName}`);
    (0, _log().default)('All done!');
  }, true);
  const vapidSubjectDescription = 'URL or `mailto:` URL which provides a point of contact in case the push service needs to contact the message sender.';
  program.command('push:web:upload [project-dir]').description('Uploads VAPID key pair and VAPID subject for web push notifications.').option('--vapid-pubkey [vapid-public-key]', 'URL-safe base64-encoded VAPID public key.').option('--vapid-pvtkey [vapid-private-key]', 'URL-safe base64-encoded VAPID private key.').option('--vapid-subject [vapid-subject]', vapidSubjectDescription).asyncActionProjectDir(async (projectDir, options) => {
    if (!options.vapidPubkey || !options.vapidPvtkey || !options.vapidSubject) {
      throw new Error('Must specify all three fields (--vapid-pubkey, --vapid-pvtkey, and --vapid-subject) to upload.');
    }

    await _uploadWebPushCredientials(projectDir, options);
  }, true);
  program.command('push:web:generate [project-dir]').description('Generates VAPID key pair for web push notifications.').option('--vapid-subject [vapid-subject]', vapidSubjectDescription).asyncActionProjectDir(async (projectDir, options) => {
    if (!options.vapidSubject) {
      throw new Error('Must specify --vapid-subject.');
    }

    const results = await _uploadWebPushCredientials(projectDir, options);
    (0, _log().default)(_chalk().default.green(`Your VAPID public key is: ${results.vapidPublicKey}`));
    (0, _log().default)(_chalk().default.green(`Your VAPID private key is: ${results.vapidPrivateKey}`));
  }, true);
  program.command('push:web:show [project-dir]').description('Prints the VAPID public key, the VAPID private key, and the VAPID subject currently in use for web notifications for this project.').asyncActionProjectDir(async projectDir => {
    const {
      args: {
        remotePackageName
      }
    } = await _xdl().Exp.getPublishInfoAsync(projectDir);
    const user = await _xdl().UserManager.getCurrentUserAsync();

    const apiClient = _xdl().ApiV2.clientForUser(user);

    const result = await apiClient.getAsync(`credentials/push/web/${remotePackageName}`);

    if (result.status === 'ok' && result.vapidPublicKey && result.vapidPrivateKey && result.vapidSubject) {
      (0, _log().default)(JSON.stringify(result));
    } else if (result.status === 'error') {
      throw new Error(`Server returned an error: ${result.error}`);
    } else {
      throw new Error('Server returned an invalid result!');
    }
  }, true);
  program.command('push:web:clear [project-dir]').description('Deletes previously uploaded VAPID public key, VAPID private key, and VAPID subject.').asyncActionProjectDir(async projectDir => {
    (0, _log().default)('Reading project configuration...');
    const {
      args: {
        remotePackageName
      }
    } = await _xdl().Exp.getPublishInfoAsync(projectDir);
    (0, _log().default)('Logging in...');
    const user = await _xdl().UserManager.getCurrentUserAsync();

    const apiClient = _xdl().ApiV2.clientForUser(user);

    (0, _log().default)("Deleting API key from Expo's servers...");
    await apiClient.deleteAsync(`credentials/push/web/${remotePackageName}`);
  }, true);
}

async function _uploadWebPushCredientials(projectDir, options) {
  const isGeneration = !(options.vapidPubkey && options.vapidPvtkey);
  (0, _log().default)('Reading project configuration...');
  const {
    args: {
      remotePackageName
    }
  } = await _xdl().Exp.getPublishInfoAsync(projectDir);
  (0, _log().default)('Logging in...');
  const user = await _xdl().UserManager.getCurrentUserAsync();

  const apiClient = _xdl().ApiV2.clientForUser(user);

  if (isGeneration) {
    (0, _log().default)("Generating and setting VAPID keys on Expo's servers...");
  } else {
    (0, _log().default)("Uploading VAPID keys to Expo's servers...");
  }

  const results = await apiClient.putAsync(`credentials/push/web/${remotePackageName}`, {
    vapidPublicKey: options.vapidPubkey,
    vapidPrivateKey: options.vapidPvtkey,
    vapidSubject: options.vapidSubject
  });

  if (results.oldVapidData && results.oldVapidData.vapidPublicKey !== results.vapidPublicKey) {
    (0, _log().default)(_chalk().default.yellow(`Warning: You have previously stored another VAPID key pair on Expo's servers. Your current action has overridden the old key pair. This means that all your web clients will not receive any new notifications from you until you have deployed the app containing the new VAPID public key, and that the user has visited the site again since then.`));
    (0, _log().default)(_chalk().default.yellow(`For your records:`));
    (0, _log().default)(_chalk().default.yellow(`- Your old VAPID public key: ${results.oldVapidData.vapidPublicKey}`));
    (0, _log().default)(_chalk().default.yellow(`- Your old VAPID private key: ${results.oldVapidData.vapidPrivateKey}`));
    (0, _log().default)(_chalk().default.yellow(`- Your old VAPID subject: ${results.oldVapidData.vapidSubject}`));
    (0, _log().default)(_chalk().default.yellow(`If you wish to undo the current action, you can use the following command to upload your old credentials back to Expo's servers:`));
    (0, _log().default)(_chalk().default.yellowBright(`expo push:web:upload --vapid-pubkey ${results.oldVapidData.vapidPublicKey} --vapid-pvtkey ${results.oldVapidData.vapidPrivateKey} --vapid-subject ${results.oldVapidData.vapidSubject}`));
  }

  (0, _log().default)(_chalk().default.green(`VAPID data uploaded!`));
  /**
   * Customize app.json
   */

  (0, _log().default)(`Reading app.json...`);
  const {
    configPath
  } = await ConfigUtils().findConfigFileAsync(projectDir);
  const appJson = JSON.parse((await _fsExtra().default.readFile(configPath).then(value => value.toString())));
  let changedProperties = [];

  if (user) {
    if (appJson.expo.owner && appJson.expo.owner !== user.username) {
      (0, _log().default)(_chalk().default.yellow(`Warning: expo.owner is already configured to be "${appJson.expo.owner}" in app.json, but your current username is "${user.username}". You will not receive any push notification if you do not change expo.owner to "${user.username}" in app.json. Alternatively, you could choose to login to "${appJson.expo.owner}" and then execute this command again.`));
    } else {
      appJson.expo.owner = user.username;
      changedProperties.push('expo.owner');
    }
  }

  if (appJson.expo.notification && appJson.expo.notification.vapidPublicKey && appJson.expo.notification.vapidPublicKey !== results.vapidPublicKey) {
    (0, _log().default)(_chalk().default.cyan(`Notice: expo.notification.vapidPublicKey is already configured in app.json (${appJson.expo.notification.vapidPublicKey}), but it is different from the VAPID public key you just ${isGeneration ? `generated` : `uploaded`}. We will replace it with the new VAPID public key.`));
  }

  if (!appJson.expo.notification) {
    appJson.expo.notification = {};
  }

  appJson.expo.notification.vapidPublicKey = results.vapidPublicKey;
  changedProperties.push('expo.notification.vapidPublicKey');

  if (changedProperties.length) {
    (0, _log().default)(`Writing to app.json...`);
    await _fsExtra().default.writeFile(configPath, JSON.stringify(appJson, null, 2));
    (0, _log().default)(_chalk().default.green(`Wrote ${changedProperties.join(', ')} to app.json.`));
  }

  (0, _log().default)(_chalk().default.green('All done!'));
  return results;
}
//# sourceMappingURL=../__sourcemaps__/commands/push-creds.js.map