UNPKG

@small-tech/node-pebble

Version:

A Node.js wrapper for Let’s Encrypt’s Pebble (“a small RFC 8555 ACME test server not suited for a production certificate authority”).

112 lines (91 loc) 3.72 kB
#!/usr/bin/env node //////////////////////////////////////////////////////////////////////////////// // // npm post-install script // // Downloads and installs the version of pebble specified in the code. // //////////////////////////////////////////////////////////////////////////////// import os from 'os' import fs from 'fs' import path from 'path' import https from 'https' import { extract } from 'tar' const __dirname = new URL('.', import.meta.url).pathname async function secureGet (url) { return new Promise((resolve, reject) => { https.get(url, response => { const statusCode = response.statusCode const location = response.headers.location // Reject if it’s not one of the status codes we are testing. if (statusCode !== 200 && statusCode !== 302) { reject({statusCode}) } let body = '' response.on('data', _ => body += _) response.on('end', () => { resolve({statusCode, location, body}) }) }) }) } async function secureStreamToFile (url, filePath) { return new Promise((resolve, reject) => { const fileStream = fs.createWriteStream(filePath) https.get(url, response => { response.pipe(fileStream) fileStream.on('finish', () => { fileStream.close() resolve() }) fileStream.on('error', error => { fs.unlinkSync(filePath) reject(error) }) }) }) } // // Sanity check: ensure we’re on a supported platform (Linux or Windows) and bail if not. // const _platform = os.platform() if (_platform !== 'darwin' && _platform !== 'linux' && _platform !== 'win32' ) { throw new Error(`Node Pebble Error: unsupported platform (only Linux and Windows is supported, not ${_platform}).`) } // // Install the Pebble binary. // const PEBBLE_VERSION = 'v2.7.0' const architecture = os.arch() const platform = _platform === 'win32' ? 'windows' : _platform const binaryExtension = _platform === 'win32' ? '.exe' : '' const binaryName = `pebble${binaryExtension}` const binaryPath = path.join(__dirname, binaryName) const downloadFileName = `pebble-${platform}-${architecture}.tar.gz` const downloadUrl = `https://github.com/letsencrypt/pebble/releases/download/${PEBBLE_VERSION}/${downloadFileName}` console.log('du', downloadUrl) const archivePath = path.join(__dirname, downloadFileName) console.log(' Node Pebble (postinstall)') console.log(' ────────────────────────────────────────────────────────────────────────') process.stdout.write(` ╰─ Removing old Pebble archive and binary (if any)… `) fs.rmSync(archivePath, {force: true}) fs.rmSync(binaryPath, {force: true}) process.stdout.write('done.\n') process.stdout.write(` ╰─ Downloading Pebble ${PEBBLE_VERSION} archive… `) const binaryRedirectUrl = (await secureGet(downloadUrl)).location await secureStreamToFile(binaryRedirectUrl, archivePath) process.stdout.write('done.\n') process.stdout.write(` ╰─ Unarchiving Pebble archive… `) await extract({ cwd: __dirname, file: archivePath, strip: 3 }) process.stdout.write('done.\n') process.stdout.write(` ╰─ Making the binary executable… `) fs.chmodSync(binaryPath, 0o755) process.stdout.write('done.\n') process.stdout.write(` ╰─ Deleting Pebble archive… `) fs.rmSync(archivePath) process.stdout.write('done.\n') console.log(' ────────────────────────────────────────────────────────────────────────')