Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 10

- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
74 changes: 65 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,75 @@
name: CI
on:
push:
branches: ['master']
branches:
- main
- 'v*'
pull_request:
branches: ['*']
paths-ignore:
- LICENSE
- '*.md'

name: CI

jobs:
test:
lint:
permissions:
contents: read
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: v24.x
cache: 'npm'
cache-dependency-path: package.json

- name: Install dependencies
run: npm install
- name: Check linting
run: npm run lint:ci

tests:
permissions:
contents: read
name: Tests
strategy:
fail-fast: false
matrix:
node-version: [18, 17, 16, 14]
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [20, 22, 24]
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
cache: 'npm'
cache-dependency-path: package.json

- name: Install Dependencies
run: npm install

- name: Run Tests
# TODO: extend to test:ci
run: npm run test

automerge:
if: >
github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]'
needs:
- tests
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Merge Dependabot PR
uses: fastify/github-action-merge-dependabot@e820d631adb1d8ab16c3b93e5afe713450884a4a # v3.11.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
35 changes: 35 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/// <reference types="node" />
import { SelfsignedOptions, CertificateField } from 'selfsigned';

type CertificateAttribute = CertificateField;

type HttpsPEMGenerateOpts = {
attr?: CertificateAttribute[];
opts?: SelfsignedOptions;
};
type HttpsPEMGenerateResult = {
key: string;
cert: string;
};

type HttpsPEM = {
key: string | null;
cert: string | null;
generate(config?: HttpsPEMGenerateOpts): Promise<HttpsPEMGenerateResult>;
generate(
config: HttpsPEMGenerateOpts | null,
done: (err: Error | null, result: HttpsPEMGenerateResult) => void
): void;
};

export default HttpsPEM;
export declare const key: HttpsPEM['key'];
export declare const cert: HttpsPEM['cert'];
export declare const generate: HttpsPEM['generate'];

export {
SelfsignedOptions,
CertificateAttribute,
HttpsPEMGenerateResult,
HttpsPEMGenerateOpts,
};
32 changes: 28 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
'use strict'

const path = require('path')
const fs = require('fs')
const path = require('node:path')
const fs = require('node:fs')

exports.key = fs.readFileSync(path.join(__dirname, 'key.pem'))
exports.cert = fs.readFileSync(path.join(__dirname, 'cert.pem'))
let selfsigned
const keyPath = path.join(__dirname, 'key.pem')
const certPath = path.join(__dirname, 'cert.pem')

// In case npm scripts are disabled, we still want to provide the key and cert
exports.key = fs.existsSync(keyPath) ? fs.readFileSync(keyPath) : null
exports.cert = fs.existsSync(certPath) ? fs.readFileSync(certPath) : null
exports.generate = generate
exports.default = exports

function generate ({ attr, opts } = { attr: [], opts: null }, done) {
if (done == null) {
const promise = new Promise((resolve, reject) => {
generate({ attr, opts }, (err, pems) => {
if (err) return reject(err)
resolve({ key: pems.private, cert: pems.cert })
})
})

return promise
}

if (!selfsigned) selfsigned = require('selfsigned')

selfsigned.generate(attr, opts, done)
}
12 changes: 9 additions & 3 deletions install.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
'use strict'

const fs = require('fs')
const path = require('path')
const fs = require('node:fs')
const path = require('node:path')
const selfsigned = require('selfsigned')

const pems = selfsigned.generate()
const nodeVersion = Number(process.versions.node.split('.')[0])
const pems =
// Due to new version of openssl, we need to use a larger key size
// for node 24 and above, otherwise the default key size is sufficient
nodeVersion > 22
? selfsigned.generate({}, { keySize: 2048 })
: selfsigned.generate()

fs.writeFileSync(path.join(__dirname, 'key.pem'), pems.private)
fs.writeFileSync(path.join(__dirname, 'cert.pem'), pems.cert)
48 changes: 39 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
{
"name": "https-pem",
"version": "3.0.0",
"description": "Self-signed PEM key and certificate ready for use in your HTTPS server",
"name": "@metcoder95/https-pem",
"version": "1.0.0",
"description": "Self-signed PEM key and certificate ready for use in your HTTPS server (fork from https-pem)",
"main": "index.js",
"types": "index.d.ts",
"private": false,
"scripts": {
"postinstall": "node install.js",
"test": "standard && node test.js"
"clean": "rm -rf *.pem",
"lint": "standard",
"lint:ci": "standard | snazzy",
"test": "node tests/index.js",
"test:ts": "tsd"
},
"repository": {
"type": "git",
"url": "git+https://github.com/watson/https-pem.git"
"url": "git+https://github.com/metcoder95/https-pem.git"
},
"engines": {
"node": ">=20"
},
"keywords": [
"tls",
Expand All @@ -26,16 +35,37 @@
"server"
],
"author": "Thomas Watson Steen <w@tson.dk> (https://twitter.com/wa7son)",
"contributors": [
{
"name": "Carlos Fuentes",
"email": "me@metcoder.dev",
"url": "https://bsky.app/profile/metcoder.dev"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/watson/https-pem/issues"
"url": "https://github.com/metcoder95/https-pem/issues"
},
"homepage": "https://github.com/watson/https-pem#readme",
"homepage": "https://github.com/metcoder95/https-pem#readme",
"dependencies": {
"selfsigned": "^2.0.1"
"selfsigned": "^3.0.1"
},
"devDependencies": {
"standard": "^17.0.0"
"@types/node": "^24.2.0",
"snazzy": "^9.0.0",
"standard": "^17.0.0",
"tsd": "^0.33.0",
"typescript": "^5.9.2",
"undici": "^7.13.0"
},
"tsd": {
"directory": "test"
},
"standard": {
"ignore": [
"*.d.ts",
"*.test-d.ts"
]
},
"coordinates": [
55.7774667,
Expand Down
23 changes: 0 additions & 23 deletions test.js

This file was deleted.

60 changes: 60 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict'

const https = require('node:https')
const { once } = require('node:events')
const { test } = require('node:test')

const { Agent } = require('undici')

const client = new Agent({
connect: {
rejectUnauthorized: false
}
})

test('https-pem (default)', async t => {
const pem = require('..')
const server = https.createServer(pem, function (req, res) {
res.end('foo')
})

server.listen()
await once(server, 'listening')
t.after(() => server.close())

const response = await client.request({
origin: `https://localhost:${server.address().port}`,
path: '/',
method: 'GET'
})

t.plan(2)
t.assert.strictEqual(response.statusCode, 200)
t.assert.strictEqual(await response.body.text(), 'foo')
})

test('https-pem (generate)', async t => {
const pem = require('..')
const pems = await pem.generate({
attr: [{ name: 'commonName', value: 'localhost' }],
opts: { keySize: 5120 }
})

const server = https.createServer(pems, function (req, res) {
res.end('foo')
})

server.listen()
await once(server, 'listening')
t.after(() => server.close())

const response = await client.request({
origin: `https://localhost:${server.address().port}`,
path: '/',
method: 'GET'
})

t.plan(2)
t.assert.strictEqual(response.statusCode, 200)
t.assert.strictEqual(await response.body.text(), 'foo')
})
19 changes: 19 additions & 0 deletions tests/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expectAssignable } from 'tsd';

import {
generate,
key,
cert,
HttpsPEMGenerateResult,
HttpsPEMGenerateOpts,
} from '..';

expectAssignable<string | null>(key);
expectAssignable<string | null>(cert);
expectAssignable<Promise<HttpsPEMGenerateResult>>(generate({}));
expectAssignable<void>(generate({}, () => {}));
expectAssignable<void>(generate(null, () => {}));
expectAssignable<HttpsPEMGenerateOpts>({
attr: [{ name: 'hello', value: 'world' }],
opts: { keySize: 1234 },
});
Loading
Loading