@small-tech/auto-encrypt
Version:
Automatically provisions and renews Let’s Encrypt TLS certificates on Node.js https servers (including Kitten, Polka, Express.js, etc.)
112 lines (89 loc) • 4.23 kB
JavaScript
////////////////////////////////////////////////////////////////////////////////
//
// Identity (abstract base class; do not use directly).
//
// Generates, stores, loads, and saves an identity from/to the file
// storage settings path. Meant to be subclassed and instantiated by different
// singletons for different types of Identity (e.g., AccountIdentity and
// DomainIdentity).
//
// The private key uses the RS256 algorithm with a 2048-bit key.
//
// Copyright © 2020 Aral Balkan, Small Technology Foundation.
// License: AGPLv3 or later.
//
////////////////////////////////////////////////////////////////////////////////
import util from 'util'
import fs from 'fs'
import jose from 'jose'
import Throws from './util/Throws.js'
import log from './util/log.js'
const throws = new Throws({
[ ]: identityFilePath => `The identity file path passed (${identityFilePath}) is for an unsupported identity type.`
})
export default class Identity {
constructor (configuration = throws.ifMissing(), identityFilePathKey = throws.ifMissing()) {
const identityFilePath = configuration[identityFilePathKey]
if (identityFilePath === undefined) {
throws.error(Symbol.for('UnsupportedIdentityType'))
}
log(` 👤 ❨auto-encrypt❩ Creating identity (${identityFilePath})`)
this.#identityFilePath = identityFilePath
if (!fs.existsSync(this.#identityFilePath)) {
// The identity file does not already exist, generate and save it.
this._key = jose.JWK.generateSync('RSA')
fs.writeFileSync(this.
} else {
// Load the key from storage.
const _privatePEM = fs.readFileSync(this.
this._key = jose.JWK.asKey(_privatePEM)
}
}
//
// Accessors.
//
// The JSON Web Key (JWK) instance.
// https://github.com/panva/jose/blob/master/docs/README.md#jwk-json-web-key.
get key () { return this._key }
// Returns the private key in PEM format.s
get privatePEM () { return this._key.toPEM(/* private = */ true) }
// The JWK thumbprint as calculated according to
// RFC 7638 (https://tools.ietf.org/html/rfc7638).
get thumbprint () { return this._key.thumbprint }
// Returns JWK-formatted objects.
// https://github.com/panva/jose/blob/master/docs/README.md#keytojwkprivate.
get privateJWK () { return this._key.toJWK(/* private = */ true) }
get publicJWK () { return this._key.toJWK() }
// The file path of the private key (saved in PEM format).
get filePath () { return this.
//
// Control access to read-only properties.
//
set key (value) { throws.error(Symbol.for('ReadOnlyAccessorError'), 'key') }
set privatePEM (value) { throws.error(Symbol.for('ReadOnlyAccessorError'), 'privatePEM') }
set thumbprint (value) { throws.error(Symbol.for('ReadOnlyAccessorError'), 'thumbprint') }
set privateJWK (value) { throws.error(Symbol.for('ReadOnlyAccessorError'), 'privateJWK') }
set publicJWK (value) { throws.error(Symbol.for('ReadOnlyAccessorError'), 'publicJWK') }
set filePath (value) { throws.error(Symbol.for('ReadOnlyAccessorError'), 'filePath') }
// Custom object description for console output (for debugging).
[ ] () {
return `
Generates, stores, loads, and saves an identity (JWT OKP key using
Ed25519 curve) from/to file storage.
- Identity file path: ${this.filePath}
- .key : the jose.JWK.RSAKey instance
- .privatePEM : PEM representation of the private key
- .thumbprint : JWK thumbprint calculated according to RFC 7638
- .privateJWK : JavaScript object representation of JWK (private key)
- .publicJWK : JavaScript object representation of JWK (public key)
- .filePath : The file path of the private key (saved in PEM format)
To see key details, please log() the .key property.
`
}
//
// Private
//
#identityFilePath = null
}