"use strict";

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

function _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

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

  _chalk = function () {
    return data;
  };

  return data;
}

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

  _fsExtra = 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 _credentials() {
  const data = require("../../credentials");

  _credentials = function () {
    return data;
  };

  return data;
}

function _AndroidCredentials() {
  const data = require("../../credentials/views/AndroidCredentials");

  _AndroidCredentials = 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

class AppSigningOptInProcess {
  // Keystore used to sign production app
  // Keystore used to sign app before uploading to Google Play store
  // private signing key and public cert extracted from signKeystore and encrypted using Google Play encryption key.
  // public cert extracted from upload keystore
  constructor(projectDir) {
    _defineProperty(this, "projectDir", '');

    _defineProperty(this, "signKeystore", '');

    _defineProperty(this, "uploadKeystore", '');

    _defineProperty(this, "privateSigningKey", '');

    _defineProperty(this, "publicUploadCert", '');

    _defineProperty(this, "uploadKeystoreCredentials", {});

    _defineProperty(this, "signKeystoreCredentials", {});

    this.projectDir = projectDir;
  }

  async run() {
    const ctx = new (_credentials().Context)();
    await ctx.init(this.projectDir);
    await this.init(ctx.manifest.slug);
    const view = new (_AndroidCredentials().DownloadKeystore)(ctx.manifest.slug);
    await view.fetch(ctx);
    await view.save(ctx, this.signKeystore, true);
    this.signKeystoreCredentials = {
      keystorePassword: (0, _get().default)(view, 'credentials.keystorePassword'),
      keyAlias: (0, _get().default)(view, 'credentials.keyAlias'),
      keyPassword: (0, _get().default)(view, 'credentials.keyPassword')
    };

    try {
      await this.exportPrivateKey();
      await this.prepareKeystores(ctx.user.username, ctx.manifest);
    } catch (error) {
      _log().default.error(error);

      await this.cleanup(true);
      return;
    }

    await this.afterStoreSubmit(ctx.user.username, ctx.manifest);
  }

  async init(slug) {
    _log().default.warn('Make sure you are not using Google Play App Signing already as this process will remove your current keystore from Expo servers.');

    (0, _log().default)(`You can check whether you are using Google Play App Signing here: ${_chalk().default.underline('https://play.google.com/apps/publish')}. Select your app and go to "Release management" → "App signing" tab. If you are already using Google Play App Signing, there will be a message that says, "App Signing by Google Play is enabled for this app", at the top of the page.`);
    const confirmQuestion = [{
      type: 'confirm',
      name: 'confirm',
      message: 'Is Google Play App Signing enabled for this app?'
    }];
    const {
      confirm: confirmEnabled
    } = await (0, _prompt().default)(confirmQuestion);

    if (confirmEnabled) {
      (0, _log().default)('Google Play App Signing is already enabled; there is nothing to do here.');
      process.exit(0);
    }

    this.signKeystore = _path().default.join(this.projectDir, `${slug}_sign.jks.bak`);
    this.uploadKeystore = _path().default.join(this.projectDir, `${slug}_upload.jks.tmp`);
    this.privateSigningKey = _path().default.join(this.projectDir, `${slug}_private_sign_key`);
    this.publicUploadCert = _path().default.join(this.projectDir, `${slug}_upload_cert.pem`);
    await this.cleanup(true);
  }

  async exportPrivateKey() {
    (0, _log().default)(`Go to the "App signing" tab in the Google Play console, select "${_chalk().default.bold('Export and upload a key (not using a Java keystore)')}" and copy the encryption key that is listed in step 1.`);
    const encryptKeyQuestion = [{
      type: 'input',
      name: 'encryptionKey',
      message: 'Google Play encryption key',
      validate: value => value.length === 136 && /^[A-Fa-f0-9]+$/.test(value) || 'Encryption key needs to be a hex-encoded 68-byte string (a 4-byte identity followed by a 64-byte P-256 point).'
    }];
    const {
      encryptionKey
    } = await (0, _prompt().default)(encryptKeyQuestion);
    await _xdl().AndroidCredentials.exportPrivateKey({
      keystorePath: this.signKeystore,
      ...this.signKeystoreCredentials
    }, encryptionKey, this.privateSigningKey);
  }

  async prepareKeystores(username, exp) {
    (0, _log().default)(`Saving upload keystore to ${this.uploadKeystore}...`);
    this.uploadKeystoreCredentials = await _xdl().AndroidCredentials.generateUploadKeystore(this.uploadKeystore, (0, _get().default)(exp, 'android.package'), `@${username}/${exp.slug}`);
    (0, _log().default)(`Saving upload certificate to ${this.publicUploadCert}`);
    await _xdl().AndroidCredentials.exportCertBase64({
      keystorePath: this.uploadKeystore,
      keystorePassword: this.uploadKeystoreCredentials.keystorePassword,
      keyAlias: this.uploadKeystoreCredentials.keyAlias
    }, this.publicUploadCert);
    await _xdl().AndroidCredentials.logKeystoreCredentials(this.uploadKeystoreCredentials, 'Credentials for upload keystore');
    (0, _log().default)('App signing certificate');
    await _xdl().AndroidCredentials.logKeystoreHashes({
      keystorePath: this.signKeystore,
      ...this.signKeystoreCredentials
    });
    (0, _log().default)('Upload certificate');
    await _xdl().AndroidCredentials.logKeystoreHashes({
      keystorePath: this.uploadKeystore,
      ...this.uploadKeystoreCredentials
    });
  }

  async afterStoreSubmit(username, exp) {
    _log().default.warn(`On the previously opened Google Play console page, upload ${_chalk().default.underline(this.privateSigningKey)} as "${_chalk().default.bold('APP SIGNING PRIVATE KEY')}" and ${_chalk().default.underline(this.publicUploadCert)} as "${_chalk().default.bold('UPLOAD KEY PUBLIC CERTIFICATE')}"`);

    _log().default.warn(`The next step will ${_chalk().default.red('remove your current keystore from Expo servers')}. Make sure that private key is uploaded successfully and compare the hashes displayed above with the ones printed in the console.`);

    const {
      confirm: confirmUpload
    } = await (0, _prompt().default)([{
      type: 'confirm',
      name: 'confirm',
      message: 'Is App Signing by Google Play enabled succesfully?',
      default: false
    }]);

    if (!confirmUpload) {
      await this.cleanup(true);

      _log().default.error('Aborting, no changes were applied');

      process.exit(1);
    }

    await _xdl().Credentials.updateCredentialsForPlatform('android', {
      keystorePassword: this.uploadKeystoreCredentials.keystorePassword,
      keystoreAlias: this.uploadKeystoreCredentials.keyAlias,
      keyPassword: this.uploadKeystoreCredentials.keyPassword,
      keystore: (await _fsExtra().default.readFile(this.uploadKeystore)).toString('base64')
    }, [], {
      platform: 'android',
      username,
      experienceName: `@${username}/${exp.slug}`
    });
    (0, _log().default)(`The original keystore is stored in ${this.signKeystore}; remove it only if you are sure that Google Play App Signing is enabled for your app.`);

    _xdl().AndroidCredentials.logKeystoreCredentials(this.signKeystoreCredentials, 'Credentials for original keystore');

    await this.cleanup();
  }

  async cleanup(all = false) {
    tryUnlink(this.uploadKeystore);
    tryUnlink(this.publicUploadCert);
    tryUnlink(this.privateSigningKey);

    if (all) {
      tryUnlink(this.signKeystore);
    }
  }

}

exports.default = AppSigningOptInProcess;

async function tryUnlink(file) {
  try {
    await _fsExtra().default.unlink(file);
  } catch (err) {}
}
//# sourceMappingURL=../../__sourcemaps__/commands/google-play/AppSigningOptIn.js.map