Skip to content

Commit a81c96a

Browse files
committed
Merge branch 'unbundled-binaries'
2 parents b414c4b + f97322b commit a81c96a

File tree

16 files changed

+2422
-1867
lines changed

16 files changed

+2422
-1867
lines changed

.gitattributes

Lines changed: 0 additions & 2 deletions
This file was deleted.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
node_modules
22
.nyc_output
3+
bin/pebble
4+
bin/pebble.exe
5+
coverage

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [5.0.0] - 2021-03-07
8+
9+
### Changed
10+
11+
- __Breaking change:__ Binaries are no longer bundled in the package. They are downloaded as an npm postinstall task.
12+
- Uses ECMAScript Modules (ESM; es6 modules).
13+
- Zero runtime dependencies.
14+
- Dev: now using @small-tech/esm-tape-runner.
15+
- Dev: now using c8 instead of nyc for coverage.
16+
- Dev: replaced tap-spec and tap-nyc with @small-tech/tap-monkey.
17+
718
## [4.2.4] - 2020-10-29
819

920
### Improved

LICENSE

Lines changed: 11 additions & 658 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
A Node.js wrapper for [Let’s Encrypt](https://letsencrypt.org)’s [Pebble](https://github.com/letsencrypt/pebble) (“a small RFC 8555 ACME test server not suited for a production certificate authority”).
44

5+
- Downloads the correct Pebble binary for your platform.
6+
57
- Launches and manages a single Pebble process.
68

79
- Returns a reference to the same process on future calls (safe to include in multiple unit tests where order of tests is undetermined)
@@ -10,7 +12,7 @@ A Node.js wrapper for [Let’s Encrypt](https://letsencrypt.org)’s [Pebble](ht
1012

1113
## Version and platform support
1214

13-
Supports [Pebble version 2.3.0](https://github.com/letsencrypt/pebble/releases/tag/v2.3.0) under [Node.js LTS](https://nodejs.org/en/about/releases/) on platforms with binary [Pebble releases](https://github.com/letsencrypt/pebble/releases/):
15+
Supports [Pebble version 2.3.1](https://github.com/letsencrypt/pebble/releases/tag/v2.3.1) under [Node.js LTS](https://nodejs.org/en/about/releases/) on platforms with binary [Pebble releases](https://github.com/letsencrypt/pebble/releases/):
1416

1517
- Linux AMD 64.
1618
- Windows AMD 64.
@@ -21,9 +23,13 @@ Supports [Pebble version 2.3.0](https://github.com/letsencrypt/pebble/releases/t
2123
npm i @small-tech/node-pebble
2224
```
2325

26+
As part of the post-installation process, Node Pebble will download the correct Pebble binary for your platform for use at runtime.
27+
28+
Node Pebble has zero runtime dependencies.
29+
2430
## API
2531

26-
### Pebble.ready ([args], [env]) -> Promise<ChidProcess>
32+
### Pebble.ready ([args], [env]) -> Promise&lt;ChildProcess&gt;
2733

2834
Promises to get the Pebble server ready for use. Resolves once Pebble server is launched and ready and Node.js’s TLS module has been patched to accept Pebble server’s [test certificate](https://github.com/letsencrypt/pebble#avoiding-client-https-errors) as well as its [dynamically-generated root and intermediary CA certificates](https://github.com/letsencrypt/pebble#ca-root-and-intermediate-certificates).
2935

@@ -88,27 +94,23 @@ Pebble.ready('-config customConfig.json')
8894
The following listing launches the Pebble server with its default settings and then shuts it down.
8995

9096
```js
91-
const Pebble = require('..')
92-
93-
async function main() {
94-
console.log('\n⏳ Launching Pebble server…\n')
97+
import Pebble from '@small-tech/node-pebble'
9598

96-
await Pebble.ready()
99+
console.log('\n⏳ Launching Pebble server…\n')
97100

98-
console.log('✔ Pebble server launched and ready.')
99-
console.log('✔ Node.js’s TLS module patched to accept Pebble’s CA certificates.')
101+
await Pebble.ready()
100102

101-
// Do stuff that requires Pebble here.
102-
//
103+
console.log('✔ Pebble server launched and ready.')
104+
console.log('✔ Node.js’s TLS module patched to accept Pebble’s CA certificates.')
103105

104-
console.log('\n⏳ Shutting down Pebble server…\n')
106+
// Do stuff that requires Pebble here.
107+
//
105108

106-
await Pebble.shutdown()
109+
console.log('\n⏳ Shutting down Pebble server…\n')
107110

108-
console.log('✔ Pebble server shut down.\n')
109-
}
111+
await Pebble.shutdown()
110112

111-
main()
113+
console.log('✔ Pebble server shut down.\n')
112114
```
113115

114116
## Install development dependencies (for tests and coverage)
@@ -120,13 +122,13 @@ npm install
120122
## Run test task
121123

122124
```sh
123-
npm test
125+
npm -s test
124126
```
125127

126128
## Run coverage task
127129

128130
```sh
129-
npm run coverage
131+
npm -s run coverage
130132
```
131133

132134
## Like this? Fund us!
@@ -137,7 +139,7 @@ We exist in part thanks to patronage by people like you. If you share [our visio
137139

138140
## Copyright
139141

140-
&copy; 2020 [Aral Balkan](https://ar.al), [Small Technology Foundation](https://small-tech.org).
142+
&copy; 2020-2021 [Aral Balkan](https://ar.al), [Small Technology Foundation](https://small-tech.org).
141143

142144
Let’s Encrypt is a trademark of the Internet Security Research Group (ISRG). All rights reserved. Node.js is a trademark of Joyent, Inc. and is used with its permission. We are not endorsed by or affiliated with Joyent or ISRG.
143145

bin/pebble

Lines changed: 0 additions & 3 deletions
This file was deleted.

bin/pebble.exe

Lines changed: 0 additions & 3 deletions
This file was deleted.

bin/post-install.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env node
2+
3+
////////////////////////////////////////////////////////////////////////////////
4+
//
5+
// npm post-install script
6+
//
7+
// Downloads and installs the version of pebble specified in the code.
8+
//
9+
////////////////////////////////////////////////////////////////////////////////
10+
11+
import os from 'os'
12+
import fs from 'fs'
13+
import path from 'path'
14+
import https from 'https'
15+
16+
const __dirname = new URL('.', import.meta.url).pathname
17+
18+
async function secureGet (url) {
19+
return new Promise((resolve, reject) => {
20+
https.get(url, response => {
21+
const statusCode = response.statusCode
22+
const location = response.headers.location
23+
24+
// Reject if it’s not one of the status codes we are testing.
25+
if (statusCode !== 200 && statusCode !== 302) {
26+
reject({statusCode})
27+
}
28+
29+
let body = ''
30+
response.on('data', _ => body += _)
31+
response.on('end', () => {
32+
resolve({statusCode, location, body})
33+
})
34+
})
35+
})
36+
}
37+
38+
async function secureStreamToFile (url, filePath) {
39+
return new Promise((resolve, reject) => {
40+
const fileStream = fs.createWriteStream(filePath)
41+
https.get(url, response => {
42+
response.pipe(fileStream)
43+
fileStream.on('finish', () => {
44+
fileStream.close()
45+
resolve()
46+
})
47+
fileStream.on('error', error => {
48+
fs.unlinkSync(filePath)
49+
reject(error)
50+
})
51+
})
52+
})
53+
}
54+
55+
//
56+
// Sanity check: ensure we’re on a supported platform (Linux or Windows) and bail if not.
57+
//
58+
59+
const _platform = os.platform()
60+
if (_platform !== 'win32' && _platform !== 'linux') {
61+
throw new Error(`Node Pebble Error: unsupported platform (only Linux and Windows is supported, not ${_platform}).`)
62+
}
63+
64+
//
65+
// Install the Pebble binary.
66+
//
67+
68+
const PEBBLE_VERSION = 'v2.3.1'
69+
70+
const platform = _platform === 'win32' ? 'windows' : 'linux'
71+
const binaryExtension = _platform === 'win32' ? '.exe' : ''
72+
73+
const binaryName = `pebble${binaryExtension}`
74+
const downloadUrl = `https://github.com/letsencrypt/pebble/releases/download/${PEBBLE_VERSION}/pebble_${platform}-amd64${binaryExtension}`
75+
const binaryPath = path.join(__dirname, binaryName)
76+
77+
78+
console.log(' Node Pebble (postinstall)')
79+
console.log(' ────────────────────────────────────────────────────────────────────────')
80+
81+
process.stdout.write(` ╰─ Removing old Pebble binary (if any)… `)
82+
fs.rmSync(binaryPath, {force: true})
83+
process.stdout.write('done.\n')
84+
85+
process.stdout.write(` ╰─ Downloading Pebble ${PEBBLE_VERSION} binary… `)
86+
const binaryRedirectUrl = (await secureGet(downloadUrl)).location
87+
await secureStreamToFile(binaryRedirectUrl, binaryPath)
88+
process.stdout.write('done.\n')
89+
90+
process.stdout.write(` ╰─ Making the binary executable… `)
91+
fs.chmodSync(binaryPath, 0o755)
92+
process.stdout.write('done.\n')
93+
94+
console.log(' ────────────────────────────────────────────────────────────────────────')

example/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* The Pebble Node example from the readme.
33
*/
4-
const Pebble = require('..')
4+
import Pebble from '../index.js'
55

66
async function main() {
77
console.log('\n ⏳ Launching Pebble server…\n')

index.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,23 @@
55
* not suited for a production certificate authority”).
66
*
77
* @module
8-
* @copyright © 2020 Aral Balkan, Small Technology Foundation
8+
* @Copyright © 2020-2021 Aral Balkan, Small Technology Foundation
99
* @license AGPL version 3.0 or later
1010
*/
11-
const os = require('os')
12-
const path = require('path')
13-
const childProcess = require('child_process')
14-
const log = require('./lib/util/log')
15-
const MonkeyPatchTls = require('./lib/MonkeyPatchTls')
11+
import os from 'os'
12+
import path from 'path'
13+
import childProcess from 'child_process'
14+
import log from './lib/util/log.js'
15+
import MonkeyPatchTls from './lib/MonkeyPatchTls.js'
1616

1717
const spawn = childProcess.spawn
1818

19+
const __dirname = new URL('.', import.meta.url).pathname
20+
1921
/**
2022
* @alias module
2123
*/
22-
class Pebble {
24+
export default class Pebble {
2325
/**
2426
* Promises to spawn a Pebble process and resolve the promise when the server is ready for use.
2527
*
@@ -128,5 +130,3 @@ class Pebble {
128130
*/
129131
static #pebbleProcess = null
130132
}
131-
132-
module.exports = Pebble

0 commit comments

Comments
 (0)