expo-updates
Version:
Fetches and manages remotely-hosted assets and updates to your app's JS bundle.
66 lines (56 loc) • 2.56 kB
text/typescript
import {
generateKeyPair,
generateSelfSignedCodeSigningCertificate,
convertCertificateToCertificatePEM,
convertKeyPairToPEM,
} from '@expo/code-signing-certificates';
import assert from 'assert';
import { promises as fs } from 'fs';
import path from 'path';
import { ensureDirAsync } from './utils/dir';
import { log } from './utils/log';
type Options = {
certificateValidityDurationYears: number;
keyOutput: string;
certificateOutput: string;
certificateCommonName: string;
};
export async function generateCodeSigningAsync(
projectRoot: string,
{ certificateValidityDurationYears, keyOutput, certificateOutput, certificateCommonName }: Options
) {
const validityDurationYears = Math.floor(certificateValidityDurationYears);
const certificateOutputDir = path.resolve(projectRoot, certificateOutput);
const keyOutputDir = path.resolve(projectRoot, keyOutput);
await Promise.all([ensureDirAsync(certificateOutputDir), ensureDirAsync(keyOutputDir)]);
const [certificateOutputDirContents, keyOutputDirContents] = await Promise.all([
fs.readdir(certificateOutputDir),
fs.readdir(keyOutputDir),
]);
assert(certificateOutputDirContents.length === 0, 'Certificate output directory must be empty');
assert(keyOutputDirContents.length === 0, 'Key output directory must be empty');
const keyPair = generateKeyPair();
const validityNotBefore = new Date();
const validityNotAfter = new Date();
validityNotAfter.setFullYear(validityNotAfter.getFullYear() + validityDurationYears);
const certificate = generateSelfSignedCodeSigningCertificate({
keyPair,
validityNotBefore,
validityNotAfter,
commonName: certificateCommonName,
});
const keyPairPEM = convertKeyPairToPEM(keyPair);
const certificatePEM = convertCertificateToCertificatePEM(certificate);
await Promise.all([
fs.writeFile(path.join(keyOutputDir, 'public-key.pem'), keyPairPEM.publicKeyPEM),
fs.writeFile(path.join(keyOutputDir, 'private-key.pem'), keyPairPEM.privateKeyPEM),
fs.writeFile(path.join(certificateOutputDir, 'certificate.pem'), certificatePEM),
]);
log(
`Generated public and private keys output in ${keyOutputDir}. Remember to add them to .gitignore or to encrypt them. (e.g. with git-crypt)`
);
log(`Generated code signing certificate output in ${certificateOutputDir}.`);
log(
`To automatically configure this project for code signing, run \`yarn expo-updates codesigning:configure --certificate-input-directory=${certificateOutput} --key-input-directory=${keyOutput}\`.`
);
}