@libp2p/webrtc 6.0.10 → 6.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +15 -150
- package/dist/index.min.js.map +4 -4
- package/dist/src/private-to-public/transport.browser.d.ts +58 -0
- package/dist/src/private-to-public/transport.browser.d.ts.map +1 -0
- package/dist/src/private-to-public/transport.browser.js +89 -0
- package/dist/src/private-to-public/transport.browser.js.map +1 -0
- package/dist/src/private-to-public/transport.d.ts +8 -41
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +13 -72
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/package.json +6 -5
- package/src/private-to-public/transport.browser.ts +138 -0
- package/src/private-to-public/transport.ts +27 -113
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { generateKeyPair, privateKeyToCryptoKeyPair } from '@libp2p/crypto/keys'
|
|
2
|
-
import { InvalidParametersError, NotFoundError, NotStartedError
|
|
3
|
-
import { peerIdFromString } from '@libp2p/peer-id'
|
|
4
|
-
import { CODE_P2P } from '@multiformats/multiaddr'
|
|
2
|
+
import { InvalidParametersError, NotFoundError, NotStartedError } from '@libp2p/interface'
|
|
5
3
|
import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
|
|
6
4
|
import { BasicConstraintsExtension, X509Certificate, X509CertificateGenerator } from '@peculiar/x509'
|
|
7
5
|
import { Key } from 'interface-datastore'
|
|
@@ -11,46 +9,19 @@ import { sha256 } from 'multiformats/hashes/sha2'
|
|
|
11
9
|
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
|
|
12
10
|
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
13
11
|
import { DEFAULT_CERTIFICATE_DATASTORE_KEY, DEFAULT_CERTIFICATE_LIFESPAN, DEFAULT_CERTIFICATE_PRIVATE_KEY_NAME, DEFAULT_CERTIFICATE_RENEWAL_THRESHOLD } from '../constants.js'
|
|
14
|
-
import { genUfrag } from '../util.js'
|
|
15
12
|
import { WebRTCDirectListener } from './listener.js'
|
|
16
|
-
import {
|
|
17
|
-
import { createDialerRTCPeerConnection } from './utils/get-rtcpeerconnection.js'
|
|
13
|
+
import { WebRTCDirectTransport as WebRTCDirectBrowserTransport } from './transport.browser.js'
|
|
18
14
|
import { formatAsPem } from './utils/pem.js'
|
|
19
|
-
import type {
|
|
20
|
-
import type {
|
|
21
|
-
import type { CreateListenerOptions, Transport, Listener,
|
|
22
|
-
import type { TransportManager } from '@libp2p/interface-internal'
|
|
15
|
+
import type { TransportCertificate } from '../index.js'
|
|
16
|
+
import type { WebRTCTransportDirectInit as WebRTCTransportDirectBrowserInit, WebRTCMetrics, WebRTCDirectTransportComponents } from './transport.browser.ts'
|
|
17
|
+
import type { CreateListenerOptions, Transport, Listener, PrivateKey, Startable } from '@libp2p/interface'
|
|
23
18
|
import type { Keychain } from '@libp2p/keychain'
|
|
24
19
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
25
|
-
import type { Datastore } from 'interface-datastore'
|
|
26
20
|
import type { TypedEventTarget } from 'main-event'
|
|
27
21
|
|
|
28
|
-
export
|
|
29
|
-
peerId: PeerId
|
|
30
|
-
privateKey: PrivateKey
|
|
31
|
-
metrics?: Metrics
|
|
32
|
-
logger: ComponentLogger
|
|
33
|
-
transportManager: TransportManager
|
|
34
|
-
upgrader: Upgrader
|
|
35
|
-
keychain?: Keychain
|
|
36
|
-
datastore: Datastore
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface WebRTCMetrics {
|
|
40
|
-
dialerEvents: CounterGroup
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface WebRTCTransportDirectInit {
|
|
44
|
-
/**
|
|
45
|
-
* The default configuration used by all created RTCPeerConnections
|
|
46
|
-
*/
|
|
47
|
-
rtcConfiguration?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>)
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* The default configuration used by all created RTCDataChannels
|
|
51
|
-
*/
|
|
52
|
-
dataChannel?: DataChannelOptions
|
|
22
|
+
export type { WebRTCMetrics, WebRTCDirectTransportComponents }
|
|
53
23
|
|
|
24
|
+
export interface WebRTCTransportDirectInit extends WebRTCTransportDirectBrowserInit {
|
|
54
25
|
/**
|
|
55
26
|
* Use an existing TLS certificate to secure incoming connections or supply
|
|
56
27
|
* settings to generate one.
|
|
@@ -96,44 +67,32 @@ export interface WebRTCDirectTransportCertificateEvents {
|
|
|
96
67
|
'certificate:renew': CustomEvent<TransportCertificate>
|
|
97
68
|
}
|
|
98
69
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
70
|
+
interface CertInit {
|
|
71
|
+
certificate?: TransportCertificate
|
|
72
|
+
certificateDatastoreKey?: string
|
|
73
|
+
certificateKeychainName?: string
|
|
74
|
+
certificateLifespan?: number
|
|
75
|
+
certificateRenewalThreshold?: number
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export class WebRTCDirectTransport extends WebRTCDirectBrowserTransport implements Transport, Startable {
|
|
104
79
|
private certificate?: TransportCertificate
|
|
105
80
|
private privateKey?: PrivateKey
|
|
106
81
|
private readonly emitter: TypedEventTarget<WebRTCDirectTransportCertificateEvents>
|
|
107
82
|
private renewCertificateTask?: ReturnType<typeof setTimeout>
|
|
83
|
+
private certInit: CertInit
|
|
108
84
|
|
|
109
85
|
constructor (components: WebRTCDirectTransportComponents, init: WebRTCTransportDirectInit = {}) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
this.init = init
|
|
86
|
+
super(components, init)
|
|
87
|
+
|
|
113
88
|
this.emitter = new TypedEventEmitter()
|
|
89
|
+
this.certInit = init
|
|
114
90
|
|
|
115
91
|
if (init.certificateLifespan != null && init.certificateRenewalThreshold != null && init.certificateRenewalThreshold >= init.certificateLifespan) {
|
|
116
92
|
throw new InvalidParametersError('Certificate renewal threshold must be less than certificate lifespan')
|
|
117
93
|
}
|
|
118
|
-
|
|
119
|
-
if (components.metrics != null) {
|
|
120
|
-
this.metrics = {
|
|
121
|
-
dialerEvents: components.metrics.registerCounterGroup('libp2p_webrtc-direct_dialer_events_total', {
|
|
122
|
-
label: 'event',
|
|
123
|
-
help: 'Total count of WebRTC-direct dial events by type'
|
|
124
|
-
})
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
94
|
}
|
|
128
95
|
|
|
129
|
-
readonly [transportSymbol] = true
|
|
130
|
-
|
|
131
|
-
readonly [Symbol.toStringTag] = '@libp2p/webrtc-direct'
|
|
132
|
-
|
|
133
|
-
readonly [serviceCapabilities]: string[] = [
|
|
134
|
-
'@libp2p/transport'
|
|
135
|
-
]
|
|
136
|
-
|
|
137
96
|
async start (): Promise<void> {
|
|
138
97
|
this.certificate = await this.getCertificate()
|
|
139
98
|
}
|
|
@@ -146,51 +105,6 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
|
146
105
|
this.certificate = undefined
|
|
147
106
|
}
|
|
148
107
|
|
|
149
|
-
/**
|
|
150
|
-
* Dial a given multiaddr
|
|
151
|
-
*/
|
|
152
|
-
async dial (ma: Multiaddr, options: DialTransportOptions<WebRTCDialEvents>): Promise<Connection> {
|
|
153
|
-
this.log('dial %a', ma)
|
|
154
|
-
// do not create RTCPeerConnection if the signal has already been aborted
|
|
155
|
-
options.signal.throwIfAborted()
|
|
156
|
-
|
|
157
|
-
let theirPeerId: PeerId | undefined
|
|
158
|
-
const remotePeerString = ma.getComponents().findLast(c => c.code === CODE_P2P)?.value
|
|
159
|
-
if (remotePeerString != null) {
|
|
160
|
-
theirPeerId = peerIdFromString(remotePeerString)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const ufrag = genUfrag()
|
|
164
|
-
|
|
165
|
-
// https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md#browser-to-public-server
|
|
166
|
-
const {
|
|
167
|
-
peerConnection,
|
|
168
|
-
muxerFactory
|
|
169
|
-
} = await createDialerRTCPeerConnection('client', ufrag, {
|
|
170
|
-
rtcConfiguration: typeof this.init.rtcConfiguration === 'function' ? await this.init.rtcConfiguration() : this.init.rtcConfiguration ?? {},
|
|
171
|
-
dataChannel: this.init.dataChannel
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
return await connect(peerConnection, muxerFactory, ufrag, {
|
|
176
|
-
role: 'client',
|
|
177
|
-
log: this.log,
|
|
178
|
-
logger: this.components.logger,
|
|
179
|
-
events: this.metrics?.dialerEvents,
|
|
180
|
-
signal: options.signal,
|
|
181
|
-
remoteAddr: ma,
|
|
182
|
-
dataChannel: this.init.dataChannel,
|
|
183
|
-
upgrader: options.upgrader,
|
|
184
|
-
peerId: this.components.peerId,
|
|
185
|
-
remotePeer: theirPeerId,
|
|
186
|
-
privateKey: this.components.privateKey
|
|
187
|
-
})
|
|
188
|
-
} catch (err) {
|
|
189
|
-
peerConnection.close()
|
|
190
|
-
throw err
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
108
|
/**
|
|
195
109
|
* Create a transport listener - this will throw in browsers
|
|
196
110
|
*/
|
|
@@ -222,9 +136,9 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
|
222
136
|
}
|
|
223
137
|
|
|
224
138
|
private async getCertificate (forceRenew?: boolean): Promise<TransportCertificate> {
|
|
225
|
-
if (isTransportCertificate(this.
|
|
139
|
+
if (isTransportCertificate(this.certInit.certificate)) {
|
|
226
140
|
this.log('using provided TLS certificate')
|
|
227
|
-
return this.
|
|
141
|
+
return this.certInit.certificate
|
|
228
142
|
}
|
|
229
143
|
|
|
230
144
|
const privateKey = await this.loadOrCreatePrivateKey()
|
|
@@ -242,7 +156,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
|
242
156
|
return this.privateKey
|
|
243
157
|
}
|
|
244
158
|
|
|
245
|
-
const keychainName = this.
|
|
159
|
+
const keychainName = this.certInit.certificateKeychainName ?? DEFAULT_CERTIFICATE_PRIVATE_KEY_NAME
|
|
246
160
|
const keychain = this.getKeychain()
|
|
247
161
|
|
|
248
162
|
try {
|
|
@@ -278,7 +192,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
|
278
192
|
}
|
|
279
193
|
|
|
280
194
|
let cert: X509Certificate
|
|
281
|
-
const dsKey = new Key(this.
|
|
195
|
+
const dsKey = new Key(this.certInit.certificateDatastoreKey ?? DEFAULT_CERTIFICATE_DATASTORE_KEY)
|
|
282
196
|
const keyPair = await privateKeyToCryptoKeyPair(privateKey)
|
|
283
197
|
|
|
284
198
|
try {
|
|
@@ -299,7 +213,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
|
299
213
|
}
|
|
300
214
|
|
|
301
215
|
// set timeout to renew certificate
|
|
302
|
-
let renewTime = (cert.notAfter.getTime() - (this.
|
|
216
|
+
let renewTime = (cert.notAfter.getTime() - (this.certInit.certificateRenewalThreshold ?? DEFAULT_CERTIFICATE_RENEWAL_THRESHOLD)) - Date.now()
|
|
303
217
|
|
|
304
218
|
if (renewTime < 0) {
|
|
305
219
|
renewTime = 100
|
|
@@ -332,7 +246,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
|
332
246
|
const cert = new X509Certificate(buf)
|
|
333
247
|
|
|
334
248
|
// check expiry date
|
|
335
|
-
const expiryTime = cert.notAfter.getTime() - (this.
|
|
249
|
+
const expiryTime = cert.notAfter.getTime() - (this.certInit.certificateRenewalThreshold ?? DEFAULT_CERTIFICATE_RENEWAL_THRESHOLD)
|
|
336
250
|
|
|
337
251
|
if (Date.now() > expiryTime) {
|
|
338
252
|
this.log('stored TLS certificate has expired')
|
|
@@ -362,7 +276,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
|
362
276
|
|
|
363
277
|
async createCertificate (dsKey: Key, keyPair: CryptoKeyPair): Promise<X509Certificate> {
|
|
364
278
|
const notBefore = new Date()
|
|
365
|
-
const notAfter = new Date(Date.now() + (this.
|
|
279
|
+
const notAfter = new Date(Date.now() + (this.certInit.certificateLifespan ?? DEFAULT_CERTIFICATE_LIFESPAN))
|
|
366
280
|
|
|
367
281
|
// have to set ms to 0 to work around https://github.com/PeculiarVentures/x509/issues/73
|
|
368
282
|
notBefore.setMilliseconds(0)
|