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
39 changes: 13 additions & 26 deletions packages/auto-tls/src/auto-tls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@
import { DomainMapper } from './domain-mapper.js'
import { createCsr, importFromPem, loadOrCreateKey, supportedAddressesFilter } from './utils.js'
import type { AutoTLSComponents, AutoTLSInit, AutoTLS as AutoTLSInterface } from './index.js'
import type { PeerId, PrivateKey, Logger, TypedEventTarget, Libp2pEvents, AbortOptions } from '@libp2p/interface'
import type { AddressManager } from '@libp2p/interface-internal'
import type { Keychain } from '@libp2p/keychain'
import type { Logger, AbortOptions } from '@libp2p/interface'
import type { DebouncedFunction } from '@libp2p/utils/debounce'
import type { Multiaddr } from '@multiformats/multiaddr'
import type { Datastore } from 'interface-datastore'

const RETRY_DELAY = 5_000

Expand All @@ -33,12 +30,7 @@

export class AutoTLS implements AutoTLSInterface {
private readonly log: Logger
private readonly addressManager: AddressManager
private readonly keychain: Keychain
private readonly datastore: Datastore
private readonly privateKey: PrivateKey
private readonly peerId: PeerId
private readonly events: TypedEventTarget<Libp2pEvents>
private readonly components: AutoTLSComponents
private readonly forgeEndpoint: URL
private readonly forgeDomain: string
private readonly acmeDirectory: URL
Expand All @@ -64,12 +56,7 @@

constructor (components: AutoTLSComponents, init: AutoTLSInit = {}) {
this.log = components.logger.forComponent('libp2p:auto-tls')
this.addressManager = components.addressManager
this.privateKey = components.privateKey
this.peerId = components.peerId
this.events = components.events
this.keychain = components.keychain
this.datastore = components.datastore
this.components = components
this.forgeEndpoint = new URL(init.forgeEndpoint ?? DEFAULT_FORGE_ENDPOINT)
this.forgeDomain = init.forgeDomain ?? DEFAULT_FORGE_DOMAIN
this.acmeDirectory = new URL(init.acmeDirectory ?? DEFAULT_ACME_DIRECTORY)
Expand All @@ -82,12 +69,12 @@
this.certificatePrivateKeyBits = init.certificatePrivateKeyBits ?? DEFAULT_CERTIFICATE_PRIVATE_KEY_BITS
this.certificateDatastoreKey = init.certificateDatastoreKey ?? DEFAULT_CERTIFICATE_DATASTORE_KEY
this.autoConfirmAddress = init.autoConfirmAddress ?? DEFAULT_AUTO_CONFIRM_ADDRESS
this.clientAuth = new ClientAuth(this.privateKey)
this.clientAuth = new ClientAuth(this.components.privateKey)
this.started = false
this.fetching = false
this.onSelfPeerUpdate = debounce(this._onSelfPeerUpdate.bind(this), init.provisionDelay ?? DEFAULT_PROVISION_DELAY)

const base36EncodedPeer = base36.encode(this.peerId.toCID().bytes)
const base36EncodedPeer = base36.encode(this.components.peerId.toCID().bytes)
this.domain = `${base36EncodedPeer}.${this.forgeDomain}`
this.email = `${base36EncodedPeer}@${this.forgeDomain}`

Expand Down Expand Up @@ -120,22 +107,22 @@
}

await start(this.domainMapper)
this.events.addEventListener('self:peer:update', this.onSelfPeerUpdate)
this.components.events.addEventListener('self:peer:update', this.onSelfPeerUpdate)
this.shutdownController = new AbortController()
setMaxListeners(Infinity, this.shutdownController.signal)
this.started = true
}

async stop (): Promise<void> {
this.events.removeEventListener('self:peer:update', this.onSelfPeerUpdate)
this.components.events.removeEventListener('self:peer:update', this.onSelfPeerUpdate)
this.shutdownController?.abort()
clearTimeout(this.renewTimeout)
await stop(this.onSelfPeerUpdate, this.domainMapper)
this.started = false
}

private _onSelfPeerUpdate (): void {
const addresses = this.addressManager.getAddresses()
const addresses = this.components.addressManager.getAddresses()
.filter(supportedAddressesFilter)

if (addresses.length === 0) {
Expand Down Expand Up @@ -187,7 +174,7 @@
private async fetchCertificate (multiaddrs: Multiaddr[], options?: AbortOptions): Promise<void> {
this.log('fetching certificate')

const certificatePrivateKey = await loadOrCreateKey(this.keychain, this.certificatePrivateKeyName, this.certificatePrivateKeyBits)
const certificatePrivateKey = await loadOrCreateKey(this.components.keychain, this.certificatePrivateKeyName, this.certificatePrivateKeyBits)
const { pem, cert } = await this.loadOrCreateCertificate(certificatePrivateKey, multiaddrs, options)

let event: CertificateEvent = 'certificate:provision'
Expand Down Expand Up @@ -221,7 +208,7 @@

// emit a certificate event
this.log('dispatching %s', event)
this.events.safeDispatchEvent(event, {
this.components.events.safeDispatchEvent(event, {
detail: {
...this.certificate
}
Expand All @@ -247,7 +234,7 @@
const cert = new X509Certificate(pem)

// cache cert
await this.datastore.put(new Key(this.certificateDatastoreKey), uint8ArrayFromString(pem))
await this.components.datastore.put(new Key(this.certificateDatastoreKey), uint8ArrayFromString(pem))

return {
pem,
Expand All @@ -260,7 +247,7 @@

try {
this.log.trace('try to load existing certificate')
const buf = await this.datastore.get(key)
const buf = await this.components.datastore.get(key)
const pem = uint8ArrayToString(buf)
const cert = new X509Certificate(pem)

Expand Down Expand Up @@ -297,7 +284,7 @@
async fetchAcmeCertificate (csr: string, multiaddrs: Multiaddr[], options?: AbortOptions): Promise<string> {
const client = new acme.Client({
directoryUrl: this.acmeDirectory.toString(),
accountKey: await loadOrCreateKey(this.keychain, this.accountPrivateKeyName, this.accountPrivateKeyBits)
accountKey: await loadOrCreateKey(this.components.keychain, this.accountPrivateKeyName, this.accountPrivateKeyBits)

Check warning on line 287 in packages/auto-tls/src/auto-tls.ts

View check run for this annotation

Codecov / codecov/patch

packages/auto-tls/src/auto-tls.ts#L287

Added line #L287 was not covered by tests
})

return client.auto({
Expand Down
2 changes: 1 addition & 1 deletion packages/auto-tls/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @packageDocumentation
*
* When a publicly dialable address is detected, use the p2p-forge service at
* https://registration.libp2p.direct to acquire a valid Let's Encrypted-backed
* https://registration.libp2p.direct to acquire a valid Let's Encrypt-backed
* TLS certificate, which the node can then use with the relevant transports.
*
* The node must be configured with a listener for at least one of the following
Expand Down
Loading