@dxos/edge-client 0.6.13 → 0.6.14-main.69511f5
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/lib/browser/chunk-ZWJXA37R.mjs +113 -0
- package/dist/lib/browser/chunk-ZWJXA37R.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +469 -160
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +125 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node/chunk-ANV2HBEH.cjs +136 -0
- package/dist/lib/node/chunk-ANV2HBEH.cjs.map +7 -0
- package/dist/lib/node/index.cjs +468 -158
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +155 -0
- package/dist/lib/node/testing/index.cjs.map +7 -0
- package/dist/lib/node-esm/chunk-HNVT57AU.mjs +115 -0
- package/dist/lib/node-esm/chunk-HNVT57AU.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +787 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/testing/index.mjs +126 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/auth.d.ts +22 -0
- package/dist/types/src/auth.d.ts.map +1 -0
- package/dist/types/src/defs.d.ts.map +1 -1
- package/dist/types/src/edge-client.d.ts +14 -13
- package/dist/types/src/edge-client.d.ts.map +1 -1
- package/dist/types/src/edge-http-client.d.ts +48 -0
- package/dist/types/src/edge-http-client.d.ts.map +1 -0
- package/dist/types/src/edge-identity.d.ts +15 -0
- package/dist/types/src/edge-identity.d.ts.map +1 -0
- package/dist/types/src/errors.d.ts +4 -1
- package/dist/types/src/errors.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/protocol.d.ts +2 -2
- package/dist/types/src/protocol.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/test-utils.d.ts +21 -0
- package/dist/types/src/testing/test-utils.d.ts.map +1 -0
- package/dist/types/src/utils.d.ts +2 -0
- package/dist/types/src/utils.d.ts.map +1 -0
- package/package.json +27 -17
- package/src/auth.ts +135 -0
- package/src/defs.ts +2 -3
- package/src/edge-client.test.ts +50 -18
- package/src/edge-client.ts +76 -24
- package/src/edge-http-client.ts +210 -0
- package/src/edge-identity.ts +31 -0
- package/src/errors.ts +8 -2
- package/src/index.ts +4 -0
- package/src/persistent-lifecycle.test.ts +2 -2
- package/src/protocol.test.ts +1 -2
- package/src/protocol.ts +2 -2
- package/src/testing/index.ts +5 -0
- package/src/testing/test-utils.ts +114 -0
- package/src/utils.ts +10 -0
- package/src/websocket.test.ts +5 -4
- package/dist/types/src/test-utils.d.ts +0 -11
- package/dist/types/src/test-utils.d.ts.map +0 -1
- package/src/test-utils.ts +0 -49
package/dist/lib/node/index.cjs
CHANGED
|
@@ -30,129 +30,86 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var node_exports = {};
|
|
31
31
|
__export(node_exports, {
|
|
32
32
|
EdgeClient: () => EdgeClient,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
EdgeConnectionClosedError: () => EdgeConnectionClosedError,
|
|
34
|
+
EdgeHttpClient: () => EdgeHttpClient,
|
|
35
|
+
EdgeIdentityChangedError: () => EdgeIdentityChangedError,
|
|
36
|
+
Protocol: () => import_chunk_ANV2HBEH.Protocol,
|
|
37
|
+
createChainEdgeIdentity: () => createChainEdgeIdentity,
|
|
38
|
+
createDeviceEdgeIdentity: () => createDeviceEdgeIdentity,
|
|
39
|
+
createEphemeralEdgeIdentity: () => createEphemeralEdgeIdentity,
|
|
40
|
+
createStubEdgeIdentity: () => createStubEdgeIdentity,
|
|
41
|
+
createTestHaloEdgeIdentity: () => createTestHaloEdgeIdentity,
|
|
42
|
+
getTypename: () => import_chunk_ANV2HBEH.getTypename,
|
|
43
|
+
handleAuthChallenge: () => handleAuthChallenge,
|
|
44
|
+
protocol: () => import_chunk_ANV2HBEH.protocol,
|
|
45
|
+
toUint8Array: () => import_chunk_ANV2HBEH.toUint8Array
|
|
37
46
|
});
|
|
38
47
|
module.exports = __toCommonJS(node_exports);
|
|
48
|
+
var import_chunk_ANV2HBEH = require("./chunk-ANV2HBEH.cjs");
|
|
39
49
|
__reExport(node_exports, require("@dxos/protocols/buf/dxos/edge/messenger_pb"), module.exports);
|
|
40
50
|
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
|
|
41
51
|
var import_async = require("@dxos/async");
|
|
42
52
|
var import_context = require("@dxos/context");
|
|
43
|
-
var import_invariant = require("@dxos/invariant");
|
|
44
53
|
var import_log = require("@dxos/log");
|
|
45
54
|
var import_buf = require("@dxos/protocols/buf");
|
|
46
55
|
var import_messenger_pb = require("@dxos/protocols/buf/dxos/edge/messenger_pb");
|
|
47
|
-
var
|
|
48
|
-
var
|
|
49
|
-
var import_invariant2 = require("@dxos/invariant");
|
|
50
|
-
var import_buf2 = require("@dxos/protocols/buf");
|
|
51
|
-
var import_messenger_pb3 = require("@dxos/protocols/buf/dxos/edge/messenger_pb");
|
|
52
|
-
var import_util = require("@dxos/util");
|
|
56
|
+
var import_invariant = require("@dxos/invariant");
|
|
57
|
+
var import_proto = require("@dxos/protocols/proto");
|
|
53
58
|
var import_async2 = require("@dxos/async");
|
|
54
59
|
var import_context2 = require("@dxos/context");
|
|
55
60
|
var import_debug = require("@dxos/debug");
|
|
56
61
|
var import_log2 = require("@dxos/log");
|
|
57
|
-
var
|
|
58
|
-
var
|
|
59
|
-
var
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"bufWkt.anyIs(message.payload, type)",
|
|
100
|
-
"`Unexpected payload type: ${payloadTypename}}`"
|
|
101
|
-
]
|
|
102
|
-
});
|
|
103
|
-
const payload = import_buf2.bufWkt.anyUnpack(message.payload, this.typeRegistry);
|
|
104
|
-
(0, import_invariant2.invariant)(payload, `Empty payload: ${payloadTypename}}`, {
|
|
105
|
-
F: __dxlog_file,
|
|
106
|
-
L: 48,
|
|
107
|
-
S: this,
|
|
108
|
-
A: [
|
|
109
|
-
"payload",
|
|
110
|
-
"`Empty payload: ${payloadTypename}}`"
|
|
111
|
-
]
|
|
112
|
-
});
|
|
113
|
-
return payload;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Get the payload type.
|
|
117
|
-
*/
|
|
118
|
-
getPayloadType(message) {
|
|
119
|
-
if (!message.payload) {
|
|
120
|
-
return void 0;
|
|
121
|
-
}
|
|
122
|
-
const [, type] = message.payload.typeUrl.split("/");
|
|
123
|
-
return type;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Create a packed message.
|
|
127
|
-
*/
|
|
128
|
-
createMessage(type, { source, target, payload, serviceId }) {
|
|
129
|
-
return import_buf2.buf.create(import_messenger_pb3.MessageSchema, {
|
|
130
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
131
|
-
source,
|
|
132
|
-
target,
|
|
133
|
-
serviceId,
|
|
134
|
-
payload: payload ? import_buf2.bufWkt.anyPack(type, import_buf2.buf.create(type, payload)) : void 0
|
|
135
|
-
});
|
|
136
|
-
}
|
|
62
|
+
var import_credentials = require("@dxos/credentials");
|
|
63
|
+
var import_keyring = require("@dxos/keyring");
|
|
64
|
+
var import_keys = require("@dxos/keys");
|
|
65
|
+
var import_async3 = require("@dxos/async");
|
|
66
|
+
var import_context3 = require("@dxos/context");
|
|
67
|
+
var import_log3 = require("@dxos/log");
|
|
68
|
+
var import_protocols = require("@dxos/protocols");
|
|
69
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-identity.ts";
|
|
70
|
+
var handleAuthChallenge = async (failedResponse, identity) => {
|
|
71
|
+
(0, import_invariant.invariant)(failedResponse.status === 401, void 0, {
|
|
72
|
+
F: __dxlog_file,
|
|
73
|
+
L: 21,
|
|
74
|
+
S: void 0,
|
|
75
|
+
A: [
|
|
76
|
+
"failedResponse.status === 401",
|
|
77
|
+
""
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
const headerValue = failedResponse.headers.get("Www-Authenticate");
|
|
81
|
+
(0, import_invariant.invariant)(headerValue?.startsWith("VerifiablePresentation challenge="), void 0, {
|
|
82
|
+
F: __dxlog_file,
|
|
83
|
+
L: 24,
|
|
84
|
+
S: void 0,
|
|
85
|
+
A: [
|
|
86
|
+
"headerValue?.startsWith('VerifiablePresentation challenge=')",
|
|
87
|
+
""
|
|
88
|
+
]
|
|
89
|
+
});
|
|
90
|
+
const challenge = headerValue?.slice("VerifiablePresentation challenge=".length);
|
|
91
|
+
(0, import_invariant.invariant)(challenge, void 0, {
|
|
92
|
+
F: __dxlog_file,
|
|
93
|
+
L: 27,
|
|
94
|
+
S: void 0,
|
|
95
|
+
A: [
|
|
96
|
+
"challenge",
|
|
97
|
+
""
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
const presentation = await identity.presentCredentials({
|
|
101
|
+
challenge: Buffer.from(challenge, "base64")
|
|
102
|
+
});
|
|
103
|
+
return import_proto.schema.getCodecForType("dxos.halo.credentials.Presentation").encode(presentation);
|
|
137
104
|
};
|
|
138
|
-
var
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
if (data instanceof Blob) {
|
|
143
|
-
return new Uint8Array(await data.arrayBuffer());
|
|
105
|
+
var EdgeConnectionClosedError = class extends Error {
|
|
106
|
+
constructor() {
|
|
107
|
+
super("Edge connection closed.");
|
|
144
108
|
}
|
|
145
|
-
throw new Error(`Unexpected datatype: ${data}`);
|
|
146
109
|
};
|
|
147
|
-
var
|
|
148
|
-
import_messenger_pb2.SwarmRequestSchema,
|
|
149
|
-
import_messenger_pb2.SwarmResponseSchema,
|
|
150
|
-
import_messenger_pb2.TextMessageSchema,
|
|
151
|
-
import_wkt.AnySchema
|
|
152
|
-
]);
|
|
153
|
-
var WebsocketClosedError = class extends Error {
|
|
110
|
+
var EdgeIdentityChangedError = class extends Error {
|
|
154
111
|
constructor() {
|
|
155
|
-
super("
|
|
112
|
+
super("Edge identity changed.");
|
|
156
113
|
}
|
|
157
114
|
};
|
|
158
115
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -242,16 +199,22 @@ _ts_decorate([
|
|
|
242
199
|
_ts_decorate([
|
|
243
200
|
import_async2.synchronized
|
|
244
201
|
], PersistentLifecycle.prototype, "scheduleRestart", null);
|
|
202
|
+
var getEdgeUrlWithProtocol = (baseUrl, protocol2) => {
|
|
203
|
+
const isSecure = baseUrl.startsWith("https") || baseUrl.startsWith("wss");
|
|
204
|
+
const url = new URL(baseUrl);
|
|
205
|
+
url.protocol = protocol2 + (isSecure ? "s" : "");
|
|
206
|
+
return url.toString();
|
|
207
|
+
};
|
|
245
208
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-client.ts";
|
|
246
209
|
var DEFAULT_TIMEOUT = 1e4;
|
|
247
210
|
var SIGNAL_KEEPALIVE_INTERVAL = 5e3;
|
|
248
211
|
var EdgeClient = class extends import_context.Resource {
|
|
249
|
-
constructor(
|
|
212
|
+
constructor(_identity, _config) {
|
|
250
213
|
super();
|
|
251
|
-
this.
|
|
252
|
-
this._peerKey = _peerKey;
|
|
214
|
+
this._identity = _identity;
|
|
253
215
|
this._config = _config;
|
|
254
216
|
this.reconnect = new import_async.Event();
|
|
217
|
+
this.connected = new import_async.Event();
|
|
255
218
|
this._persistentLifecycle = new PersistentLifecycle({
|
|
256
219
|
start: async () => this._openWebSocket(),
|
|
257
220
|
stop: async () => this._closeWebSocket(),
|
|
@@ -262,26 +225,40 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
262
225
|
this._ws = void 0;
|
|
263
226
|
this._keepaliveCtx = void 0;
|
|
264
227
|
this._heartBeatContext = void 0;
|
|
265
|
-
this.
|
|
228
|
+
this._baseWsUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "ws");
|
|
229
|
+
this._baseHttpUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, "http");
|
|
266
230
|
}
|
|
267
231
|
// TODO(burdon): Attach logging.
|
|
268
232
|
get info() {
|
|
269
233
|
return {
|
|
270
234
|
open: this.isOpen,
|
|
271
|
-
identity: this.
|
|
272
|
-
device: this.
|
|
235
|
+
identity: this._identity.identityKey,
|
|
236
|
+
device: this._identity.peerKey
|
|
273
237
|
};
|
|
274
238
|
}
|
|
239
|
+
get isConnected() {
|
|
240
|
+
return Boolean(this._ws) && this._ready.state === import_async.TriggerState.RESOLVED;
|
|
241
|
+
}
|
|
275
242
|
get identityKey() {
|
|
276
|
-
return this.
|
|
243
|
+
return this._identity.identityKey;
|
|
277
244
|
}
|
|
278
245
|
get peerKey() {
|
|
279
|
-
return this.
|
|
246
|
+
return this._identity.peerKey;
|
|
280
247
|
}
|
|
281
|
-
setIdentity(
|
|
282
|
-
this.
|
|
283
|
-
|
|
284
|
-
|
|
248
|
+
setIdentity(identity) {
|
|
249
|
+
if (identity.identityKey !== this._identity.identityKey || identity.peerKey !== this._identity.peerKey) {
|
|
250
|
+
(0, import_log.log)("Edge identity changed", {
|
|
251
|
+
identity,
|
|
252
|
+
oldIdentity: this._identity
|
|
253
|
+
}, {
|
|
254
|
+
F: __dxlog_file3,
|
|
255
|
+
L: 99,
|
|
256
|
+
S: this,
|
|
257
|
+
C: (f, a) => f(...a)
|
|
258
|
+
});
|
|
259
|
+
this._identity = identity;
|
|
260
|
+
this._persistentLifecycle.scheduleRestart();
|
|
261
|
+
}
|
|
285
262
|
}
|
|
286
263
|
addListener(listener) {
|
|
287
264
|
this._listeners.add(listener);
|
|
@@ -295,7 +272,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
295
272
|
info: this.info
|
|
296
273
|
}, {
|
|
297
274
|
F: __dxlog_file3,
|
|
298
|
-
L:
|
|
275
|
+
L: 114,
|
|
299
276
|
S: this,
|
|
300
277
|
C: (f, a) => f(...a)
|
|
301
278
|
});
|
|
@@ -304,7 +281,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
304
281
|
err
|
|
305
282
|
}, {
|
|
306
283
|
F: __dxlog_file3,
|
|
307
|
-
L:
|
|
284
|
+
L: 116,
|
|
308
285
|
S: this,
|
|
309
286
|
C: (f, a) => f(...a)
|
|
310
287
|
});
|
|
@@ -315,31 +292,48 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
315
292
|
*/
|
|
316
293
|
async _close() {
|
|
317
294
|
(0, import_log.log)("closing...", {
|
|
318
|
-
peerKey: this.
|
|
295
|
+
peerKey: this._identity.peerKey
|
|
319
296
|
}, {
|
|
320
297
|
F: __dxlog_file3,
|
|
321
|
-
L:
|
|
298
|
+
L: 124,
|
|
322
299
|
S: this,
|
|
323
300
|
C: (f, a) => f(...a)
|
|
324
301
|
});
|
|
325
302
|
await this._persistentLifecycle.close();
|
|
326
303
|
}
|
|
327
304
|
async _openWebSocket() {
|
|
328
|
-
|
|
329
|
-
|
|
305
|
+
if (this._ctx.disposed) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const path = `/ws/${this._identity.identityKey}/${this._identity.peerKey}`;
|
|
309
|
+
const protocolHeader = this._config.disableAuth ? void 0 : await this._createAuthHeader(path);
|
|
310
|
+
const url = new URL(path, this._baseWsUrl);
|
|
311
|
+
(0, import_log.log)("Opening websocket", {
|
|
312
|
+
url: url.toString(),
|
|
313
|
+
protocolHeader
|
|
314
|
+
}, {
|
|
315
|
+
F: __dxlog_file3,
|
|
316
|
+
L: 136,
|
|
317
|
+
S: this,
|
|
318
|
+
C: (f, a) => f(...a)
|
|
319
|
+
});
|
|
320
|
+
this._ws = new import_isomorphic_ws.default(url, protocolHeader ? [
|
|
321
|
+
protocolHeader
|
|
322
|
+
] : []);
|
|
330
323
|
this._ws.onopen = () => {
|
|
331
324
|
(0, import_log.log)("opened", this.info, {
|
|
332
325
|
F: __dxlog_file3,
|
|
333
|
-
L:
|
|
326
|
+
L: 140,
|
|
334
327
|
S: this,
|
|
335
328
|
C: (f, a) => f(...a)
|
|
336
329
|
});
|
|
337
330
|
this._ready.wake();
|
|
331
|
+
this.connected.emit();
|
|
338
332
|
};
|
|
339
333
|
this._ws.onclose = () => {
|
|
340
334
|
(0, import_log.log)("closed", this.info, {
|
|
341
335
|
F: __dxlog_file3,
|
|
342
|
-
L:
|
|
336
|
+
L: 145,
|
|
343
337
|
S: this,
|
|
344
338
|
C: (f, a) => f(...a)
|
|
345
339
|
});
|
|
@@ -351,7 +345,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
351
345
|
info: event.message
|
|
352
346
|
}, {
|
|
353
347
|
F: __dxlog_file3,
|
|
354
|
-
L:
|
|
348
|
+
L: 149,
|
|
355
349
|
S: this,
|
|
356
350
|
C: (f, a) => f(...a)
|
|
357
351
|
});
|
|
@@ -362,14 +356,14 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
362
356
|
this._onHeartbeat();
|
|
363
357
|
return;
|
|
364
358
|
}
|
|
365
|
-
const data = await toUint8Array(event.data);
|
|
359
|
+
const data = await (0, import_chunk_ANV2HBEH.toUint8Array)(event.data);
|
|
366
360
|
const message = import_buf.buf.fromBinary(import_messenger_pb.MessageSchema, data);
|
|
367
361
|
(0, import_log.log)("received", {
|
|
368
|
-
peerKey: this.
|
|
369
|
-
payload: protocol.getPayloadType(message)
|
|
362
|
+
peerKey: this._identity.peerKey,
|
|
363
|
+
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
370
364
|
}, {
|
|
371
365
|
F: __dxlog_file3,
|
|
372
|
-
L:
|
|
366
|
+
L: 162,
|
|
373
367
|
S: this,
|
|
374
368
|
C: (f, a) => f(...a)
|
|
375
369
|
});
|
|
@@ -380,10 +374,10 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
380
374
|
} catch (err) {
|
|
381
375
|
import_log.log.error("processing", {
|
|
382
376
|
err,
|
|
383
|
-
payload: protocol.getPayloadType(message)
|
|
377
|
+
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
384
378
|
}, {
|
|
385
379
|
F: __dxlog_file3,
|
|
386
|
-
L:
|
|
380
|
+
L: 168,
|
|
387
381
|
S: this,
|
|
388
382
|
C: (f, a) => f(...a)
|
|
389
383
|
});
|
|
@@ -394,9 +388,18 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
394
388
|
await this._ready.wait({
|
|
395
389
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
396
390
|
});
|
|
391
|
+
(0, import_log.log)("Websocket is ready", {
|
|
392
|
+
identity: this._identity.identityKey,
|
|
393
|
+
peer: this._identity.peerKey
|
|
394
|
+
}, {
|
|
395
|
+
F: __dxlog_file3,
|
|
396
|
+
L: 176,
|
|
397
|
+
S: this,
|
|
398
|
+
C: (f, a) => f(...a)
|
|
399
|
+
});
|
|
397
400
|
this._keepaliveCtx = new import_context.Context(void 0, {
|
|
398
401
|
F: __dxlog_file3,
|
|
399
|
-
L:
|
|
402
|
+
L: 179
|
|
400
403
|
});
|
|
401
404
|
(0, import_async.scheduleTaskInterval)(this._keepaliveCtx, async () => {
|
|
402
405
|
this._ws?.send("__ping__");
|
|
@@ -409,7 +412,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
409
412
|
return;
|
|
410
413
|
}
|
|
411
414
|
try {
|
|
412
|
-
this._ready.throw(new
|
|
415
|
+
this._ready.throw(this.isOpen ? new EdgeIdentityChangedError() : new EdgeConnectionClosedError());
|
|
413
416
|
this._ready.reset();
|
|
414
417
|
void this._keepaliveCtx?.dispose();
|
|
415
418
|
this._keepaliveCtx = void 0;
|
|
@@ -431,7 +434,7 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
431
434
|
err
|
|
432
435
|
}, {
|
|
433
436
|
F: __dxlog_file3,
|
|
434
|
-
L:
|
|
437
|
+
L: 215,
|
|
435
438
|
S: this,
|
|
436
439
|
C: (f, a) => f(...a)
|
|
437
440
|
});
|
|
@@ -443,34 +446,28 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
443
446
|
*/
|
|
444
447
|
async send(message) {
|
|
445
448
|
if (this._ready.state !== import_async.TriggerState.RESOLVED) {
|
|
449
|
+
(0, import_log.log)("waiting for websocket to become ready", void 0, {
|
|
450
|
+
F: __dxlog_file3,
|
|
451
|
+
L: 225,
|
|
452
|
+
S: this,
|
|
453
|
+
C: (f, a) => f(...a)
|
|
454
|
+
});
|
|
446
455
|
await this._ready.wait({
|
|
447
456
|
timeout: this._config.timeout ?? DEFAULT_TIMEOUT
|
|
448
457
|
});
|
|
449
458
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
""
|
|
457
|
-
]
|
|
458
|
-
});
|
|
459
|
-
(0, import_invariant.invariant)(!message.source || message.source.peerKey === this._peerKey, void 0, {
|
|
460
|
-
F: __dxlog_file3,
|
|
461
|
-
L: 203,
|
|
462
|
-
S: this,
|
|
463
|
-
A: [
|
|
464
|
-
"!message.source || message.source.peerKey === this._peerKey",
|
|
465
|
-
""
|
|
466
|
-
]
|
|
467
|
-
});
|
|
459
|
+
if (!this._ws) {
|
|
460
|
+
throw new EdgeConnectionClosedError();
|
|
461
|
+
}
|
|
462
|
+
if (message.source && (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)) {
|
|
463
|
+
throw new EdgeIdentityChangedError();
|
|
464
|
+
}
|
|
468
465
|
(0, import_log.log)("sending...", {
|
|
469
|
-
peerKey: this.
|
|
470
|
-
payload: protocol.getPayloadType(message)
|
|
466
|
+
peerKey: this._identity.peerKey,
|
|
467
|
+
payload: import_chunk_ANV2HBEH.protocol.getPayloadType(message)
|
|
471
468
|
}, {
|
|
472
469
|
F: __dxlog_file3,
|
|
473
|
-
L:
|
|
470
|
+
L: 238,
|
|
474
471
|
S: this,
|
|
475
472
|
C: (f, a) => f(...a)
|
|
476
473
|
});
|
|
@@ -483,18 +480,331 @@ var EdgeClient = class extends import_context.Resource {
|
|
|
483
480
|
void this._heartBeatContext?.dispose();
|
|
484
481
|
this._heartBeatContext = new import_context.Context(void 0, {
|
|
485
482
|
F: __dxlog_file3,
|
|
486
|
-
L:
|
|
483
|
+
L: 247
|
|
487
484
|
});
|
|
488
485
|
(0, import_async.scheduleTask)(this._heartBeatContext, () => {
|
|
489
486
|
this._persistentLifecycle.scheduleRestart();
|
|
490
487
|
}, 2 * SIGNAL_KEEPALIVE_INTERVAL);
|
|
491
488
|
}
|
|
489
|
+
async _createAuthHeader(path) {
|
|
490
|
+
const httpUrl = new URL(path, this._baseHttpUrl);
|
|
491
|
+
httpUrl.protocol = getEdgeUrlWithProtocol(this._baseWsUrl.toString(), "http");
|
|
492
|
+
const response = await fetch(httpUrl, {
|
|
493
|
+
method: "GET"
|
|
494
|
+
});
|
|
495
|
+
if (response.status === 401) {
|
|
496
|
+
return encodePresentationWsAuthHeader(await handleAuthChallenge(response, this._identity));
|
|
497
|
+
} else {
|
|
498
|
+
import_log.log.warn("no auth challenge from edge", {
|
|
499
|
+
status: response.status,
|
|
500
|
+
statusText: response.statusText
|
|
501
|
+
}, {
|
|
502
|
+
F: __dxlog_file3,
|
|
503
|
+
L: 264,
|
|
504
|
+
S: this,
|
|
505
|
+
C: (f, a) => f(...a)
|
|
506
|
+
});
|
|
507
|
+
return void 0;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
var encodePresentationWsAuthHeader = (encodedPresentation) => {
|
|
512
|
+
const encodedToken = Buffer.from(encodedPresentation).toString("base64").replace(/=*$/, "").replaceAll("/", "|");
|
|
513
|
+
return `base64url.bearer.authorization.dxos.org.${encodedToken}`;
|
|
514
|
+
};
|
|
515
|
+
var createDeviceEdgeIdentity = async (signer, key) => {
|
|
516
|
+
return {
|
|
517
|
+
identityKey: key.toHex(),
|
|
518
|
+
peerKey: key.toHex(),
|
|
519
|
+
presentCredentials: async ({ challenge }) => {
|
|
520
|
+
return (0, import_credentials.signPresentation)({
|
|
521
|
+
presentation: {
|
|
522
|
+
credentials: [
|
|
523
|
+
// Verifier requires at least one credential in the presentation to establish the subject.
|
|
524
|
+
await (0, import_credentials.createCredential)({
|
|
525
|
+
assertion: {
|
|
526
|
+
"@type": "dxos.halo.credentials.Auth"
|
|
527
|
+
},
|
|
528
|
+
issuer: key,
|
|
529
|
+
subject: key,
|
|
530
|
+
signer
|
|
531
|
+
})
|
|
532
|
+
]
|
|
533
|
+
},
|
|
534
|
+
signer,
|
|
535
|
+
signerKey: key,
|
|
536
|
+
nonce: challenge
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
};
|
|
541
|
+
var createChainEdgeIdentity = async (signer, identityKey, peerKey, chain, credentials) => {
|
|
542
|
+
const credentialsToSign = credentials.length > 0 ? credentials : [
|
|
543
|
+
await (0, import_credentials.createCredential)({
|
|
544
|
+
assertion: {
|
|
545
|
+
"@type": "dxos.halo.credentials.Auth"
|
|
546
|
+
},
|
|
547
|
+
issuer: identityKey,
|
|
548
|
+
subject: identityKey,
|
|
549
|
+
signer,
|
|
550
|
+
chain,
|
|
551
|
+
signingKey: peerKey
|
|
552
|
+
})
|
|
553
|
+
];
|
|
554
|
+
return {
|
|
555
|
+
identityKey: identityKey.toHex(),
|
|
556
|
+
peerKey: peerKey.toHex(),
|
|
557
|
+
presentCredentials: async ({ challenge }) => {
|
|
558
|
+
return (0, import_credentials.signPresentation)({
|
|
559
|
+
presentation: {
|
|
560
|
+
credentials: credentialsToSign
|
|
561
|
+
},
|
|
562
|
+
signer,
|
|
563
|
+
nonce: challenge,
|
|
564
|
+
signerKey: peerKey,
|
|
565
|
+
chain
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
};
|
|
570
|
+
var createEphemeralEdgeIdentity = async () => {
|
|
571
|
+
const keyring = new import_keyring.Keyring();
|
|
572
|
+
const key = await keyring.createKey();
|
|
573
|
+
return createDeviceEdgeIdentity(keyring, key);
|
|
574
|
+
};
|
|
575
|
+
var createTestHaloEdgeIdentity = async (signer, identityKey, deviceKey) => {
|
|
576
|
+
const deviceAdmission = await (0, import_credentials.createCredential)({
|
|
577
|
+
assertion: {
|
|
578
|
+
"@type": "dxos.halo.credentials.AuthorizedDevice",
|
|
579
|
+
deviceKey,
|
|
580
|
+
identityKey
|
|
581
|
+
},
|
|
582
|
+
issuer: identityKey,
|
|
583
|
+
subject: deviceKey,
|
|
584
|
+
signer
|
|
585
|
+
});
|
|
586
|
+
return createChainEdgeIdentity(signer, identityKey, deviceKey, {
|
|
587
|
+
credential: deviceAdmission
|
|
588
|
+
}, [
|
|
589
|
+
await (0, import_credentials.createCredential)({
|
|
590
|
+
assertion: {
|
|
591
|
+
"@type": "dxos.halo.credentials.Auth"
|
|
592
|
+
},
|
|
593
|
+
issuer: identityKey,
|
|
594
|
+
subject: identityKey,
|
|
595
|
+
signer
|
|
596
|
+
})
|
|
597
|
+
]);
|
|
598
|
+
};
|
|
599
|
+
var createStubEdgeIdentity = () => {
|
|
600
|
+
const identityKey = import_keys.PublicKey.random();
|
|
601
|
+
const deviceKey = import_keys.PublicKey.random();
|
|
602
|
+
return {
|
|
603
|
+
identityKey: identityKey.toHex(),
|
|
604
|
+
peerKey: deviceKey.toHex(),
|
|
605
|
+
presentCredentials: async () => {
|
|
606
|
+
throw new Error("Stub identity does not support authentication.");
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
};
|
|
610
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/mesh/edge-client/src/edge-http-client.ts";
|
|
611
|
+
var DEFAULT_RETRY_TIMEOUT = 1500;
|
|
612
|
+
var DEFAULT_RETRY_JITTER = 500;
|
|
613
|
+
var DEFAULT_MAX_RETRIES_COUNT = 3;
|
|
614
|
+
var EdgeHttpClient = class {
|
|
615
|
+
constructor(baseUrl) {
|
|
616
|
+
this._baseUrl = getEdgeUrlWithProtocol(baseUrl, "http");
|
|
617
|
+
(0, import_log3.log)("created", {
|
|
618
|
+
url: this._baseUrl
|
|
619
|
+
}, {
|
|
620
|
+
F: __dxlog_file4,
|
|
621
|
+
L: 42,
|
|
622
|
+
S: this,
|
|
623
|
+
C: (f, a) => f(...a)
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
setIdentity(identity) {
|
|
627
|
+
this._edgeIdentity = identity;
|
|
628
|
+
}
|
|
629
|
+
createAgent(body, args) {
|
|
630
|
+
return this._call("/agents/create", {
|
|
631
|
+
...args,
|
|
632
|
+
method: "POST",
|
|
633
|
+
body
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
getAgentStatus(request, args) {
|
|
637
|
+
return this._call(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, {
|
|
638
|
+
...args,
|
|
639
|
+
method: "GET"
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
getCredentialsForNotarization(spaceId, args) {
|
|
643
|
+
return this._call(`/spaces/${spaceId}/notarization`, {
|
|
644
|
+
...args,
|
|
645
|
+
method: "GET"
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
async notarizeCredentials(spaceId, body, args) {
|
|
649
|
+
await this._call(`/spaces/${spaceId}/notarization`, {
|
|
650
|
+
...args,
|
|
651
|
+
body,
|
|
652
|
+
method: "POST"
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
async joinSpaceByInvitation(spaceId, body, args) {
|
|
656
|
+
return this._call(`/spaces/${spaceId}/join`, {
|
|
657
|
+
...args,
|
|
658
|
+
body,
|
|
659
|
+
method: "POST"
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
async recoverIdentity(body, args) {
|
|
663
|
+
return this._call("/identity/recover", {
|
|
664
|
+
...args,
|
|
665
|
+
body,
|
|
666
|
+
method: "POST"
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
async _call(path, args) {
|
|
670
|
+
const requestContext = args.context ?? new import_context3.Context(void 0, {
|
|
671
|
+
F: __dxlog_file4,
|
|
672
|
+
L: 88
|
|
673
|
+
});
|
|
674
|
+
const shouldRetry = createRetryHandler(args);
|
|
675
|
+
const url = `${this._baseUrl}${path.startsWith("/") ? path.slice(1) : path}`;
|
|
676
|
+
import_log3.log.info("call", {
|
|
677
|
+
method: args.method,
|
|
678
|
+
path,
|
|
679
|
+
request: args.body
|
|
680
|
+
}, {
|
|
681
|
+
F: __dxlog_file4,
|
|
682
|
+
L: 92,
|
|
683
|
+
S: this,
|
|
684
|
+
C: (f, a) => f(...a)
|
|
685
|
+
});
|
|
686
|
+
let handledAuth = false;
|
|
687
|
+
let authHeader = this._authHeader;
|
|
688
|
+
while (true) {
|
|
689
|
+
let processingError;
|
|
690
|
+
let retryAfterHeaderValue = Number.NaN;
|
|
691
|
+
try {
|
|
692
|
+
const request = createRequest(args, authHeader);
|
|
693
|
+
const response = await fetch(url, request);
|
|
694
|
+
retryAfterHeaderValue = Number(response.headers.get("Retry-After"));
|
|
695
|
+
if (response.ok) {
|
|
696
|
+
const body = await response.json();
|
|
697
|
+
if (body.success) {
|
|
698
|
+
return body.data;
|
|
699
|
+
}
|
|
700
|
+
import_log3.log.info("unsuccessful edge response", {
|
|
701
|
+
path,
|
|
702
|
+
body
|
|
703
|
+
}, {
|
|
704
|
+
F: __dxlog_file4,
|
|
705
|
+
L: 111,
|
|
706
|
+
S: this,
|
|
707
|
+
C: (f, a) => f(...a)
|
|
708
|
+
});
|
|
709
|
+
if (body.errorData?.type === "auth_challenge" && typeof body.errorData?.challenge === "string") {
|
|
710
|
+
processingError = new import_protocols.EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
|
|
711
|
+
} else {
|
|
712
|
+
processingError = import_protocols.EdgeCallFailedError.fromUnsuccessfulResponse(response, body);
|
|
713
|
+
}
|
|
714
|
+
} else if (response.status === 401 && !handledAuth) {
|
|
715
|
+
authHeader = await this._handleUnauthorized(response);
|
|
716
|
+
handledAuth = true;
|
|
717
|
+
continue;
|
|
718
|
+
} else {
|
|
719
|
+
processingError = import_protocols.EdgeCallFailedError.fromHttpFailure(response);
|
|
720
|
+
}
|
|
721
|
+
} catch (error) {
|
|
722
|
+
processingError = import_protocols.EdgeCallFailedError.fromProcessingFailureCause(error);
|
|
723
|
+
}
|
|
724
|
+
if (processingError.isRetryable && await shouldRetry(requestContext, retryAfterHeaderValue)) {
|
|
725
|
+
import_log3.log.info("retrying edge request", {
|
|
726
|
+
path,
|
|
727
|
+
processingError
|
|
728
|
+
}, {
|
|
729
|
+
F: __dxlog_file4,
|
|
730
|
+
L: 130,
|
|
731
|
+
S: this,
|
|
732
|
+
C: (f, a) => f(...a)
|
|
733
|
+
});
|
|
734
|
+
} else {
|
|
735
|
+
throw processingError;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
async _handleUnauthorized(response) {
|
|
740
|
+
if (!this._edgeIdentity) {
|
|
741
|
+
import_log3.log.warn("edge unauthorized response received before identity was set", void 0, {
|
|
742
|
+
F: __dxlog_file4,
|
|
743
|
+
L: 139,
|
|
744
|
+
S: this,
|
|
745
|
+
C: (f, a) => f(...a)
|
|
746
|
+
});
|
|
747
|
+
throw import_protocols.EdgeCallFailedError.fromHttpFailure(response);
|
|
748
|
+
}
|
|
749
|
+
const challenge = await handleAuthChallenge(response, this._edgeIdentity);
|
|
750
|
+
this._authHeader = encodeAuthHeader(challenge);
|
|
751
|
+
(0, import_log3.log)("auth header updated", void 0, {
|
|
752
|
+
F: __dxlog_file4,
|
|
753
|
+
L: 144,
|
|
754
|
+
S: this,
|
|
755
|
+
C: (f, a) => f(...a)
|
|
756
|
+
});
|
|
757
|
+
return this._authHeader;
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
var createRetryHandler = (args) => {
|
|
761
|
+
if (!args.retry || args.retry.count < 1) {
|
|
762
|
+
return async () => false;
|
|
763
|
+
}
|
|
764
|
+
let retries = 0;
|
|
765
|
+
const maxRetries = args.retry.count ?? DEFAULT_MAX_RETRIES_COUNT;
|
|
766
|
+
const baseTimeout = args.retry.timeout ?? DEFAULT_RETRY_TIMEOUT;
|
|
767
|
+
const jitter = args.retry.jitter ?? DEFAULT_RETRY_JITTER;
|
|
768
|
+
return async (ctx, retryAfter) => {
|
|
769
|
+
if (++retries > maxRetries || ctx.disposed) {
|
|
770
|
+
return false;
|
|
771
|
+
}
|
|
772
|
+
if (retryAfter) {
|
|
773
|
+
await (0, import_async3.sleep)(retryAfter);
|
|
774
|
+
} else {
|
|
775
|
+
const timeout = baseTimeout + Math.random() * jitter;
|
|
776
|
+
await (0, import_async3.sleep)(timeout);
|
|
777
|
+
}
|
|
778
|
+
return true;
|
|
779
|
+
};
|
|
780
|
+
};
|
|
781
|
+
var createRequest = (args, authHeader) => {
|
|
782
|
+
return {
|
|
783
|
+
method: args.method,
|
|
784
|
+
body: args.body && JSON.stringify(args.body),
|
|
785
|
+
headers: authHeader ? {
|
|
786
|
+
Authorization: authHeader
|
|
787
|
+
} : void 0
|
|
788
|
+
};
|
|
789
|
+
};
|
|
790
|
+
var encodeAuthHeader = (challenge) => {
|
|
791
|
+
const encodedChallenge = Buffer.from(challenge).toString("base64");
|
|
792
|
+
return `VerifiablePresentation pb;base64,${encodedChallenge}`;
|
|
492
793
|
};
|
|
493
794
|
// Annotate the CommonJS export names for ESM import in node:
|
|
494
795
|
0 && (module.exports = {
|
|
495
796
|
EdgeClient,
|
|
797
|
+
EdgeConnectionClosedError,
|
|
798
|
+
EdgeHttpClient,
|
|
799
|
+
EdgeIdentityChangedError,
|
|
496
800
|
Protocol,
|
|
801
|
+
createChainEdgeIdentity,
|
|
802
|
+
createDeviceEdgeIdentity,
|
|
803
|
+
createEphemeralEdgeIdentity,
|
|
804
|
+
createStubEdgeIdentity,
|
|
805
|
+
createTestHaloEdgeIdentity,
|
|
497
806
|
getTypename,
|
|
807
|
+
handleAuthChallenge,
|
|
498
808
|
protocol,
|
|
499
809
|
toUint8Array,
|
|
500
810
|
...require("@dxos/protocols/buf/dxos/edge/messenger_pb")
|