@dxos/client-services 0.1.56-main.e47dfd1 → 0.1.56-main.e79d64a
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-CSJSC47N.mjs → chunk-T32PP5QD.mjs} +1284 -625
- package/dist/lib/browser/chunk-T32PP5QD.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +70 -54
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +42 -48
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +1439 -767
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +1590 -936
- package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
- package/dist/types/src/packlets/identity/identity-manager.d.ts +7 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +7 -3
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +3 -2
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts +6 -2
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/diagnostics.d.ts +46 -0
- package/dist/types/src/packlets/services/diagnostics.d.ts.map +1 -0
- package/dist/types/src/packlets/services/index.d.ts +1 -0
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/platform.d.ts +16 -0
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts +2 -1
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +7 -3
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/util.d.ts +6 -0
- package/dist/types/src/packlets/services/util.d.ts.map +1 -0
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +12 -2
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/shell-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +2 -0
- package/dist/types/src/version.d.ts.map +1 -0
- package/package.json +34 -33
- package/src/packlets/devices/devices-service.test.ts +2 -1
- package/src/packlets/identity/authenticator.test.ts +2 -2
- package/src/packlets/identity/identity-manager.test.ts +15 -3
- package/src/packlets/identity/identity-manager.ts +28 -8
- package/src/packlets/identity/identity-service.test.ts +17 -2
- package/src/packlets/identity/identity-service.ts +24 -16
- package/src/packlets/identity/identity.test.ts +7 -6
- package/src/packlets/identity/identity.ts +9 -5
- package/src/packlets/invitations/device-invitation-protocol.test.ts +2 -1
- package/src/packlets/invitations/device-invitation-protocol.ts +1 -2
- package/src/packlets/invitations/invitation-extension.ts +1 -2
- package/src/packlets/invitations/invitations-handler.ts +3 -2
- package/src/packlets/invitations/invitations-service.ts +1 -2
- package/src/packlets/invitations/space-invitation-protocol.ts +1 -2
- package/src/packlets/locks/node.ts +1 -1
- package/src/packlets/logging/logging-service.ts +17 -9
- package/src/packlets/network/network-service.test.ts +2 -1
- package/src/packlets/services/client-rpc-server.ts +4 -4
- package/src/packlets/services/diagnostics.ts +212 -0
- package/src/packlets/services/index.ts +1 -0
- package/src/packlets/services/platform.ts +48 -0
- package/src/packlets/services/service-context.test.ts +59 -0
- package/src/packlets/services/service-context.ts +21 -15
- package/src/packlets/services/service-host.test.ts +12 -11
- package/src/packlets/services/service-host.ts +39 -20
- package/src/packlets/services/service-registry.test.ts +3 -1
- package/src/packlets/services/util.ts +33 -0
- package/src/packlets/spaces/data-space-manager.test.ts +80 -22
- package/src/packlets/spaces/data-space-manager.ts +7 -4
- package/src/packlets/spaces/data-space.ts +17 -5
- package/src/packlets/spaces/notarization-plugin.ts +1 -2
- package/src/packlets/spaces/spaces-service.test.ts +2 -1
- package/src/packlets/spaces/spaces-service.ts +19 -13
- package/src/packlets/system/system-service.test.ts +1 -0
- package/src/packlets/system/system-service.ts +34 -2
- package/src/packlets/testing/invitation-utils.ts +1 -2
- package/src/packlets/testing/test-builder.ts +1 -1
- package/src/packlets/vault/iframe-host-runtime.ts +2 -1
- package/src/packlets/vault/shell-runtime.ts +1 -2
- package/src/packlets/vault/worker-runtime.ts +3 -2
- package/src/packlets/vault/worker-session.ts +7 -3
- package/src/version.ts +1 -0
- package/dist/lib/browser/chunk-CSJSC47N.mjs.map +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/client-services",
|
|
3
|
-
"version": "0.1.56-main.
|
|
3
|
+
"version": "0.1.56-main.e79d64a",
|
|
4
4
|
"description": "DXOS client services implementation",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -21,41 +21,42 @@
|
|
|
21
21
|
"src"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"@dxos/
|
|
26
|
-
"@dxos/
|
|
27
|
-
"@dxos/
|
|
28
|
-
"@dxos/
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/echo-
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/keyring": "0.1.56-main.
|
|
39
|
-
"@dxos/keys": "0.1.56-main.
|
|
40
|
-
"@dxos/lock-file": "0.1.56-main.
|
|
41
|
-
"@dxos/log": "0.1.56-main.
|
|
42
|
-
"@dxos/messaging": "0.1.56-main.
|
|
43
|
-
"@dxos/model-factory": "0.1.56-main.
|
|
44
|
-
"@dxos/network-manager": "0.1.56-main.
|
|
45
|
-
"@dxos/node-std": "0.1.56-main.
|
|
46
|
-
"@dxos/protocols": "0.1.56-main.
|
|
47
|
-
"@dxos/random-access-storage": "0.1.56-main.
|
|
48
|
-
"@dxos/rpc": "0.1.56-main.
|
|
49
|
-
"@dxos/teleport": "0.1.56-main.
|
|
50
|
-
"@dxos/teleport-extension-gossip": "0.1.56-main.
|
|
51
|
-
"@dxos/teleport-extension-object-sync": "0.1.56-main.
|
|
52
|
-
"@dxos/text-model": "0.1.56-main.
|
|
53
|
-
"@dxos/timeframe": "0.1.56-main.
|
|
54
|
-
"@dxos/
|
|
24
|
+
"@dxos/async": "0.1.56-main.e79d64a",
|
|
25
|
+
"@dxos/client-protocol": "0.1.56-main.e79d64a",
|
|
26
|
+
"@dxos/codec-protobuf": "0.1.56-main.e79d64a",
|
|
27
|
+
"@dxos/config": "0.1.56-main.e79d64a",
|
|
28
|
+
"@dxos/context": "0.1.56-main.e79d64a",
|
|
29
|
+
"@dxos/credentials": "0.1.56-main.e79d64a",
|
|
30
|
+
"@dxos/crypto": "0.1.56-main.e79d64a",
|
|
31
|
+
"@dxos/debug": "0.1.56-main.e79d64a",
|
|
32
|
+
"@dxos/document-model": "0.1.56-main.e79d64a",
|
|
33
|
+
"@dxos/echo-db": "0.1.56-main.e79d64a",
|
|
34
|
+
"@dxos/echo-pipeline": "0.1.56-main.e79d64a",
|
|
35
|
+
"@dxos/errors": "0.1.56-main.e79d64a",
|
|
36
|
+
"@dxos/feed-store": "0.1.56-main.e79d64a",
|
|
37
|
+
"@dxos/invariant": "0.1.56-main.e79d64a",
|
|
38
|
+
"@dxos/keyring": "0.1.56-main.e79d64a",
|
|
39
|
+
"@dxos/keys": "0.1.56-main.e79d64a",
|
|
40
|
+
"@dxos/lock-file": "0.1.56-main.e79d64a",
|
|
41
|
+
"@dxos/log": "0.1.56-main.e79d64a",
|
|
42
|
+
"@dxos/messaging": "0.1.56-main.e79d64a",
|
|
43
|
+
"@dxos/model-factory": "0.1.56-main.e79d64a",
|
|
44
|
+
"@dxos/network-manager": "0.1.56-main.e79d64a",
|
|
45
|
+
"@dxos/node-std": "0.1.56-main.e79d64a",
|
|
46
|
+
"@dxos/protocols": "0.1.56-main.e79d64a",
|
|
47
|
+
"@dxos/random-access-storage": "0.1.56-main.e79d64a",
|
|
48
|
+
"@dxos/rpc": "0.1.56-main.e79d64a",
|
|
49
|
+
"@dxos/teleport": "0.1.56-main.e79d64a",
|
|
50
|
+
"@dxos/teleport-extension-gossip": "0.1.56-main.e79d64a",
|
|
51
|
+
"@dxos/teleport-extension-object-sync": "0.1.56-main.e79d64a",
|
|
52
|
+
"@dxos/text-model": "0.1.56-main.e79d64a",
|
|
53
|
+
"@dxos/timeframe": "0.1.56-main.e79d64a",
|
|
54
|
+
"@dxos/tracing": "0.1.56-main.e79d64a",
|
|
55
|
+
"@dxos/util": "0.1.56-main.e79d64a"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/readable-stream": "^2.3.9",
|
|
58
|
-
"@dxos/signal": "0.1.56-main.
|
|
59
|
+
"@dxos/signal": "0.1.56-main.e79d64a"
|
|
59
60
|
},
|
|
60
61
|
"publishConfig": {
|
|
61
62
|
"access": "public"
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Trigger } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { DevicesService, Device } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
10
|
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
10
11
|
|
|
@@ -18,7 +19,7 @@ describe('DevicesService', () => {
|
|
|
18
19
|
|
|
19
20
|
beforeEach(async () => {
|
|
20
21
|
serviceContext = createServiceContext();
|
|
21
|
-
await serviceContext.open();
|
|
22
|
+
await serviceContext.open(new Context());
|
|
22
23
|
devicesService = new DevicesServiceImpl(serviceContext.identityManager);
|
|
23
24
|
});
|
|
24
25
|
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import expect from 'expect';
|
|
6
|
-
import assert from 'node:assert';
|
|
7
6
|
|
|
8
7
|
import { Event } from '@dxos/async';
|
|
9
8
|
import { createCredentialSignerWithKey } from '@dxos/credentials';
|
|
9
|
+
import { invariant } from '@dxos/invariant';
|
|
10
10
|
import { Keyring } from '@dxos/keyring';
|
|
11
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
12
|
import { describe, test } from '@dxos/test';
|
|
@@ -28,7 +28,7 @@ describe('identity/authenticator', () => {
|
|
|
28
28
|
|
|
29
29
|
const nonce = new Uint8Array([2, 1, 3, 7]);
|
|
30
30
|
const credential = await authProvider(nonce);
|
|
31
|
-
|
|
31
|
+
invariant(credential);
|
|
32
32
|
expect(await authVerifier.verifier(nonce, credential)).toBeTruthy();
|
|
33
33
|
}).onlyEnvironments('nodejs');
|
|
34
34
|
});
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { expect } from 'chai';
|
|
6
6
|
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import { valueEncoding, MetadataStore, SpaceManager, AuthStatus, SnapshotStore } from '@dxos/echo-pipeline';
|
|
8
9
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
9
10
|
import { Keyring } from '@dxos/keyring';
|
|
@@ -64,7 +65,7 @@ describe('identity/identity-manager', () => {
|
|
|
64
65
|
|
|
65
66
|
test('creates identity', async () => {
|
|
66
67
|
const { identityManager } = await setupPeer();
|
|
67
|
-
await identityManager.open();
|
|
68
|
+
await identityManager.open(new Context());
|
|
68
69
|
afterTest(() => identityManager.close());
|
|
69
70
|
|
|
70
71
|
const identity = await identityManager.createIdentity();
|
|
@@ -75,13 +76,13 @@ describe('identity/identity-manager', () => {
|
|
|
75
76
|
const storage = createStorage({ type: StorageType.RAM });
|
|
76
77
|
|
|
77
78
|
const peer1 = await setupPeer({ storage });
|
|
78
|
-
await peer1.identityManager.open();
|
|
79
|
+
await peer1.identityManager.open(new Context());
|
|
79
80
|
const identity1 = await peer1.identityManager.createIdentity();
|
|
80
81
|
await peer1.identityManager.close();
|
|
81
82
|
await peer1.feedStore.close();
|
|
82
83
|
|
|
83
84
|
const peer2 = await setupPeer({ storage });
|
|
84
|
-
await peer2.identityManager.open();
|
|
85
|
+
await peer2.identityManager.open(new Context());
|
|
85
86
|
|
|
86
87
|
expect(peer2.identityManager.identity).to.exist;
|
|
87
88
|
expect(peer2.identityManager.identity!.identityKey).to.deep.eq(identity1.identityKey);
|
|
@@ -90,6 +91,17 @@ describe('identity/identity-manager', () => {
|
|
|
90
91
|
// TODO(dmaretskyi): Check that identity is "alive" (space is working and can write mutations).
|
|
91
92
|
});
|
|
92
93
|
|
|
94
|
+
test('update profile', async () => {
|
|
95
|
+
const { identityManager } = await setupPeer();
|
|
96
|
+
await identityManager.open(new Context());
|
|
97
|
+
afterTest(() => identityManager.close());
|
|
98
|
+
|
|
99
|
+
const identity = await identityManager.createIdentity();
|
|
100
|
+
expect(identity.profileDocument?.displayName).to.be.undefined;
|
|
101
|
+
await identityManager.updateProfile({ displayName: 'Example' });
|
|
102
|
+
expect(identity.profileDocument?.displayName).to.equal('Example');
|
|
103
|
+
});
|
|
104
|
+
|
|
93
105
|
test('admit another device', async () => {
|
|
94
106
|
const signalContext = new MemorySignalManagerContext();
|
|
95
107
|
|
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from 'tiny-invariant';
|
|
6
|
-
|
|
7
5
|
import { Event } from '@dxos/async';
|
|
6
|
+
import { Context } from '@dxos/context';
|
|
8
7
|
import { createCredentialSignerWithKey, CredentialGenerator } from '@dxos/credentials';
|
|
9
8
|
import { MetadataStore, SpaceManager, SwarmIdentity } from '@dxos/echo-pipeline';
|
|
10
9
|
import { FeedStore } from '@dxos/feed-store';
|
|
10
|
+
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { Keyring } from '@dxos/keyring';
|
|
12
12
|
import { PublicKey } from '@dxos/keys';
|
|
13
13
|
import { log } from '@dxos/log';
|
|
14
14
|
import { trace } from '@dxos/protocols';
|
|
15
15
|
import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
16
16
|
import { IdentityRecord, SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
17
|
-
import { AdmittedFeed } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
17
|
+
import { AdmittedFeed, ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
18
18
|
import { Timeframe } from '@dxos/timeframe';
|
|
19
|
+
import { trace as Trace } from '@dxos/tracing';
|
|
19
20
|
import { deferFunction } from '@dxos/util';
|
|
20
21
|
|
|
21
22
|
import { createAuthProvider } from './authenticator';
|
|
@@ -47,6 +48,7 @@ export type CreateIdentityOptions = {
|
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
// TODO(dmaretskyi): Rename: represents the peer's state machine.
|
|
51
|
+
@Trace.resource()
|
|
50
52
|
export class IdentityManager {
|
|
51
53
|
readonly stateUpdate = new Event();
|
|
52
54
|
|
|
@@ -65,7 +67,8 @@ export class IdentityManager {
|
|
|
65
67
|
return this._identity;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
@Trace.span()
|
|
71
|
+
async open(ctx: Context) {
|
|
69
72
|
const traceId = PublicKey.random().toHex();
|
|
70
73
|
log.trace('dxos.halo.identity-manager.open', trace.begin({ id: traceId }));
|
|
71
74
|
await this._metadataStore.load();
|
|
@@ -74,7 +77,7 @@ export class IdentityManager {
|
|
|
74
77
|
log('identity record', { identityRecord });
|
|
75
78
|
if (identityRecord) {
|
|
76
79
|
this._identity = await this._constructIdentity(identityRecord);
|
|
77
|
-
await this._identity.open();
|
|
80
|
+
await this._identity.open(ctx);
|
|
78
81
|
await this._identity.ready();
|
|
79
82
|
log.trace('dxos.halo.identity', {
|
|
80
83
|
identityKey: identityRecord.identityKey,
|
|
@@ -86,7 +89,7 @@ export class IdentityManager {
|
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
async close() {
|
|
89
|
-
await this._identity?.close();
|
|
92
|
+
await this._identity?.close(new Context());
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
async createIdentity({ displayName }: CreateIdentityOptions = {}) {
|
|
@@ -106,7 +109,7 @@ export class IdentityManager {
|
|
|
106
109
|
};
|
|
107
110
|
|
|
108
111
|
const identity = await this._constructIdentity(identityRecord);
|
|
109
|
-
await identity.open();
|
|
112
|
+
await identity.open(new Context());
|
|
110
113
|
|
|
111
114
|
{
|
|
112
115
|
const generator = new CredentialGenerator(this._keyring, identityRecord.identityKey, identityRecord.deviceKey);
|
|
@@ -176,7 +179,7 @@ export class IdentityManager {
|
|
|
176
179
|
};
|
|
177
180
|
const identity = await this._constructIdentity(identityRecord);
|
|
178
181
|
|
|
179
|
-
await identity.open();
|
|
182
|
+
await identity.open(new Context());
|
|
180
183
|
this._identity = identity;
|
|
181
184
|
await this._metadataStore.setIdentityRecord(identityRecord);
|
|
182
185
|
await this._identity.ready();
|
|
@@ -190,6 +193,23 @@ export class IdentityManager {
|
|
|
190
193
|
return identity;
|
|
191
194
|
}
|
|
192
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Update the profile document of an existing identity.
|
|
198
|
+
*/
|
|
199
|
+
async updateProfile(profile: ProfileDocument) {
|
|
200
|
+
invariant(this._identity, 'Identity not initialized.');
|
|
201
|
+
// TODO(wittjosiah): Use CredentialGenerator.
|
|
202
|
+
const credential = await this._identity.getIdentityCredentialSigner().createCredential({
|
|
203
|
+
subject: this._identity.identityKey,
|
|
204
|
+
assertion: {
|
|
205
|
+
'@type': 'dxos.halo.credentials.IdentityProfile',
|
|
206
|
+
profile,
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
const receipt = await this._identity.controlPipeline.writer.write({ credential: { credential } });
|
|
210
|
+
await this._identity.controlPipeline.state.waitUntilTimeframe(new Timeframe([[receipt.feedKey, receipt.seq]]));
|
|
211
|
+
}
|
|
212
|
+
|
|
193
213
|
private async _constructIdentity(identityRecord: IdentityRecord) {
|
|
194
214
|
invariant(!this._identity);
|
|
195
215
|
log('constructing identity', { identityRecord });
|
|
@@ -6,6 +6,7 @@ import chai, { expect } from 'chai';
|
|
|
6
6
|
import chaiAsPromised from 'chai-as-promised';
|
|
7
7
|
|
|
8
8
|
import { Trigger } from '@dxos/async';
|
|
9
|
+
import { Context } from '@dxos/context';
|
|
9
10
|
import { PublicKey } from '@dxos/keys';
|
|
10
11
|
import { Identity, IdentityService } from '@dxos/protocols/proto/dxos/client/services';
|
|
11
12
|
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
@@ -22,8 +23,12 @@ describe('IdentityService', () => {
|
|
|
22
23
|
|
|
23
24
|
beforeEach(async () => {
|
|
24
25
|
serviceContext = createServiceContext();
|
|
25
|
-
await serviceContext.open();
|
|
26
|
-
identityService = new IdentityServiceImpl(
|
|
26
|
+
await serviceContext.open(new Context());
|
|
27
|
+
identityService = new IdentityServiceImpl(
|
|
28
|
+
(options) => serviceContext.createIdentity(options),
|
|
29
|
+
serviceContext.identityManager,
|
|
30
|
+
serviceContext.keyring,
|
|
31
|
+
);
|
|
27
32
|
});
|
|
28
33
|
|
|
29
34
|
afterEach(async () => {
|
|
@@ -54,6 +59,16 @@ describe('IdentityService', () => {
|
|
|
54
59
|
|
|
55
60
|
describe.skip('recoverIdentity', () => {});
|
|
56
61
|
|
|
62
|
+
describe('updateProfile', () => {
|
|
63
|
+
test('updates profile', async () => {
|
|
64
|
+
const identity = await identityService.createIdentity({});
|
|
65
|
+
expect(identity.profile?.displayName).to.be.undefined;
|
|
66
|
+
|
|
67
|
+
const updatedIdentity = await identityService.updateProfile({ displayName: 'Example' });
|
|
68
|
+
expect(updatedIdentity.profile?.displayName).to.equal('Example');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
57
72
|
describe('queryIdentity', () => {
|
|
58
73
|
test('returns undefined if no identity is available', async () => {
|
|
59
74
|
const query = identityService.queryIdentity();
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from 'tiny-invariant';
|
|
6
|
-
|
|
7
5
|
import { Stream } from '@dxos/codec-protobuf';
|
|
8
6
|
import { signPresentation } from '@dxos/credentials';
|
|
9
7
|
import { todo } from '@dxos/debug';
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
9
|
+
import { Keyring } from '@dxos/keyring';
|
|
10
10
|
import {
|
|
11
11
|
Identity,
|
|
12
12
|
IdentityService,
|
|
@@ -16,15 +16,17 @@ import {
|
|
|
16
16
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
17
17
|
import { Presentation, ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import { CreateIdentityOptions, IdentityManager } from './identity-manager';
|
|
20
20
|
|
|
21
21
|
export class IdentityServiceImpl implements IdentityService {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
constructor(
|
|
23
|
+
private readonly _createIdentity: (params?: CreateIdentityOptions) => Promise<Identity>,
|
|
24
|
+
private readonly _identityManager: IdentityManager,
|
|
25
|
+
private readonly _keyring: Keyring,
|
|
26
|
+
) {}
|
|
24
27
|
|
|
25
28
|
async createIdentity(request: ProfileDocument): Promise<Identity> {
|
|
26
|
-
await this.
|
|
27
|
-
|
|
29
|
+
await this._createIdentity(request);
|
|
28
30
|
return this._getIdentity()!;
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -37,30 +39,36 @@ export class IdentityServiceImpl implements IdentityService {
|
|
|
37
39
|
const emitNext = () => next({ identity: this._getIdentity() });
|
|
38
40
|
|
|
39
41
|
emitNext();
|
|
40
|
-
return this.
|
|
42
|
+
return this._identityManager.stateUpdate.on(emitNext);
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
private _getIdentity(): Identity | undefined {
|
|
45
|
-
if (!this.
|
|
47
|
+
if (!this._identityManager.identity) {
|
|
46
48
|
return undefined;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
return {
|
|
50
|
-
identityKey: this.
|
|
51
|
-
spaceKey: this.
|
|
52
|
-
profile: this.
|
|
52
|
+
identityKey: this._identityManager.identity.identityKey,
|
|
53
|
+
spaceKey: this._identityManager.identity.space.key,
|
|
54
|
+
profile: this._identityManager.identity.profileDocument,
|
|
53
55
|
};
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
async updateProfile(profile: ProfileDocument): Promise<Identity> {
|
|
59
|
+
invariant(this._identityManager.identity, 'Identity not initialized.');
|
|
60
|
+
await this._identityManager.updateProfile(profile);
|
|
61
|
+
return this._getIdentity()!;
|
|
62
|
+
}
|
|
63
|
+
|
|
56
64
|
async signPresentation({ presentation, nonce }: SignPresentationRequest): Promise<Presentation> {
|
|
57
|
-
invariant(this.
|
|
65
|
+
invariant(this._identityManager.identity, 'Identity not initialized.');
|
|
58
66
|
|
|
59
67
|
return await signPresentation({
|
|
60
68
|
presentation,
|
|
61
|
-
signer: this.
|
|
62
|
-
signerKey: this.
|
|
63
|
-
chain: this.
|
|
69
|
+
signer: this._keyring,
|
|
70
|
+
signerKey: this._identityManager.identity.deviceKey,
|
|
71
|
+
chain: this._identityManager.identity.deviceCredentialChain,
|
|
64
72
|
nonce,
|
|
65
73
|
});
|
|
66
74
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import expect from 'expect';
|
|
6
6
|
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import { CredentialGenerator, verifyCredential } from '@dxos/credentials';
|
|
8
9
|
import {
|
|
9
10
|
MetadataStore,
|
|
@@ -106,8 +107,8 @@ describe('identity/identity', () => {
|
|
|
106
107
|
space,
|
|
107
108
|
});
|
|
108
109
|
|
|
109
|
-
await identity.open();
|
|
110
|
-
afterTest(() => identity.close());
|
|
110
|
+
await identity.open(new Context());
|
|
111
|
+
afterTest(() => identity.close(new Context()));
|
|
111
112
|
|
|
112
113
|
//
|
|
113
114
|
// Identity genesis
|
|
@@ -219,8 +220,8 @@ describe('identity/identity', () => {
|
|
|
219
220
|
space,
|
|
220
221
|
}));
|
|
221
222
|
|
|
222
|
-
await identity.open();
|
|
223
|
-
afterTest(() => identity.close());
|
|
223
|
+
await identity.open(new Context());
|
|
224
|
+
afterTest(() => identity.close(new Context()));
|
|
224
225
|
|
|
225
226
|
//
|
|
226
227
|
// Identity genesis
|
|
@@ -310,8 +311,8 @@ describe('identity/identity', () => {
|
|
|
310
311
|
space,
|
|
311
312
|
}));
|
|
312
313
|
|
|
313
|
-
await identity.open();
|
|
314
|
-
afterTest(() => identity.close());
|
|
314
|
+
await identity.open(new Context());
|
|
315
|
+
afterTest(() => identity.close(new Context()));
|
|
315
316
|
}
|
|
316
317
|
|
|
317
318
|
//
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from 'tiny-invariant';
|
|
6
|
-
|
|
7
5
|
import { Event } from '@dxos/async';
|
|
8
6
|
import { AUTH_TIMEOUT, LOAD_CONTROL_FEEDS_TIMEOUT } from '@dxos/client-protocol';
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
9
8
|
import {
|
|
10
9
|
DeviceStateMachine,
|
|
11
10
|
CredentialSigner,
|
|
@@ -17,11 +16,13 @@ import { Signer } from '@dxos/crypto';
|
|
|
17
16
|
import { failUndefined } from '@dxos/debug';
|
|
18
17
|
import { Space } from '@dxos/echo-pipeline';
|
|
19
18
|
import { writeMessages } from '@dxos/feed-store';
|
|
19
|
+
import { invariant } from '@dxos/invariant';
|
|
20
20
|
import { PublicKey } from '@dxos/keys';
|
|
21
21
|
import { log } from '@dxos/log';
|
|
22
22
|
import { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
23
23
|
import { AdmittedFeed, ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
24
24
|
import { DeviceAdmissionRequest } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
25
|
+
import { trace } from '@dxos/tracing';
|
|
25
26
|
import { ComplexSet } from '@dxos/util';
|
|
26
27
|
|
|
27
28
|
import { TrustedKeySetAuthVerifier } from './authenticator';
|
|
@@ -36,6 +37,7 @@ export type IdentityParams = {
|
|
|
36
37
|
/**
|
|
37
38
|
* Agent identity manager, which includes the agent's Halo space.
|
|
38
39
|
*/
|
|
40
|
+
@trace.resource()
|
|
39
41
|
export class Identity {
|
|
40
42
|
public readonly space: Space;
|
|
41
43
|
private readonly _signer: Signer;
|
|
@@ -77,13 +79,15 @@ export class Identity {
|
|
|
77
79
|
return this._deviceStateMachine.authorizedDeviceKeys;
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
|
|
82
|
+
@trace.span()
|
|
83
|
+
async open(ctx: Context) {
|
|
81
84
|
await this.space.spaceState.addCredentialProcessor(this._deviceStateMachine);
|
|
82
85
|
await this.space.spaceState.addCredentialProcessor(this._profileStateMachine);
|
|
83
|
-
await this.space.open();
|
|
86
|
+
await this.space.open(ctx);
|
|
84
87
|
}
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
@trace.span()
|
|
90
|
+
async close(ctx: Context) {
|
|
87
91
|
await this.authVerifier.close();
|
|
88
92
|
await this.space.spaceState.removeCredentialProcessor(this._profileStateMachine);
|
|
89
93
|
await this.space.spaceState.removeCredentialProcessor(this._deviceStateMachine);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { asyncChain } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
10
|
import { describe, test, afterTest } from '@dxos/test';
|
|
10
11
|
|
|
@@ -19,7 +20,7 @@ const closeAfterTest = async (peer: ServiceContext) => {
|
|
|
19
20
|
describe('services/device', () => {
|
|
20
21
|
test('creates identity', async () => {
|
|
21
22
|
const peer = createServiceContext();
|
|
22
|
-
await peer.open();
|
|
23
|
+
await peer.open(new Context());
|
|
23
24
|
afterTest(() => peer.close());
|
|
24
25
|
|
|
25
26
|
const identity = await peer.createIdentity();
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from '
|
|
6
|
-
|
|
5
|
+
import { invariant } from '@dxos/invariant';
|
|
7
6
|
import { Keyring } from '@dxos/keyring';
|
|
8
7
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
8
|
import { AdmissionRequest, AdmissionResponse, IntroductionRequest } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from 'tiny-invariant';
|
|
6
|
-
|
|
7
5
|
import { Trigger } from '@dxos/async';
|
|
8
6
|
import { cancelWithContext, Context } from '@dxos/context';
|
|
9
7
|
import { InvalidInvitationExtensionRoleError } from '@dxos/errors';
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
10
9
|
import { PublicKey } from '@dxos/keys';
|
|
11
10
|
import { log } from '@dxos/log';
|
|
12
11
|
import { schema, trace } from '@dxos/protocols';
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from 'tiny-invariant';
|
|
6
|
-
|
|
7
5
|
import { PushStream, scheduleTask, TimeoutError, Trigger } from '@dxos/async';
|
|
8
6
|
import {
|
|
9
7
|
AuthenticatingInvitationObservable,
|
|
@@ -14,6 +12,7 @@ import {
|
|
|
14
12
|
import { Context } from '@dxos/context';
|
|
15
13
|
import { generatePasscode } from '@dxos/credentials';
|
|
16
14
|
import { InvalidInvitationExtensionRoleError } from '@dxos/errors';
|
|
15
|
+
import { invariant } from '@dxos/invariant';
|
|
17
16
|
import { PublicKey } from '@dxos/keys';
|
|
18
17
|
import { log } from '@dxos/log';
|
|
19
18
|
import { createTeleportProtocolFactory, NetworkManager, StarTopology, SwarmConnection } from '@dxos/network-manager';
|
|
@@ -187,6 +186,7 @@ export class InvitationsHandler {
|
|
|
187
186
|
teleport.addExtension('dxos.halo.invitations', createExtension());
|
|
188
187
|
}),
|
|
189
188
|
topology: new StarTopology(topic),
|
|
189
|
+
label: 'invitation host',
|
|
190
190
|
});
|
|
191
191
|
ctx.onDispose(() => swarmConnection.close());
|
|
192
192
|
|
|
@@ -363,6 +363,7 @@ export class InvitationsHandler {
|
|
|
363
363
|
teleport.addExtension('dxos.halo.invitations', createExtension());
|
|
364
364
|
}),
|
|
365
365
|
topology: new StarTopology(topic),
|
|
366
|
+
label: 'invitation guest',
|
|
366
367
|
});
|
|
367
368
|
ctx.onDispose(() => swarmConnection.close());
|
|
368
369
|
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from 'tiny-invariant';
|
|
6
|
-
|
|
7
5
|
import { Event } from '@dxos/async';
|
|
8
6
|
import { AuthenticatingInvitationObservable, CancellableInvitationObservable } from '@dxos/client-protocol';
|
|
9
7
|
import { Stream } from '@dxos/codec-protobuf';
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
10
9
|
import { log } from '@dxos/log';
|
|
11
10
|
import {
|
|
12
11
|
AuthenticationRequest,
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import invariant from 'tiny-invariant';
|
|
6
|
-
|
|
7
5
|
import { createAdmissionCredentials, getCredentialAssertion } from '@dxos/credentials';
|
|
8
6
|
import { writeMessages } from '@dxos/feed-store';
|
|
7
|
+
import { invariant } from '@dxos/invariant';
|
|
9
8
|
import { Keyring } from '@dxos/keyring';
|
|
10
9
|
import { PublicKey } from '@dxos/keys';
|
|
11
10
|
import { log } from '@dxos/log';
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ControlMetricsRequest,
|
|
14
14
|
ControlMetricsResponse,
|
|
15
15
|
QueryMetricsRequest,
|
|
16
|
+
QueryMetricsResponse,
|
|
16
17
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
17
18
|
import { jsonify, numericalValues, tracer } from '@dxos/util';
|
|
18
19
|
|
|
@@ -21,6 +22,7 @@ import { jsonify, numericalValues, tracer } from '@dxos/util';
|
|
|
21
22
|
*/
|
|
22
23
|
export class LoggingServiceImpl implements LoggingService {
|
|
23
24
|
private readonly _logs = new Event<NaturalLogEntry>();
|
|
25
|
+
private readonly _started = new Date();
|
|
24
26
|
|
|
25
27
|
async open() {
|
|
26
28
|
log.runtimeConfig.processors.push(this._logProcessor);
|
|
@@ -45,11 +47,14 @@ export class LoggingServiceImpl implements LoggingService {
|
|
|
45
47
|
return { recording: tracer.recording };
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated (Move to diagnostics).
|
|
52
|
+
*/
|
|
53
|
+
queryMetrics({ interval = 5_000 }: QueryMetricsRequest): Stream<QueryMetricsResponse> {
|
|
49
54
|
// TODO(burdon): Map all traces; how to bind to reducer/metrics shape (e.g., numericalValues)?
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
return { key, stats: numericalValues(
|
|
55
|
+
const getNumericalValues = (key: string) => {
|
|
56
|
+
const events = tracer.get(key) ?? [];
|
|
57
|
+
return { key, stats: numericalValues(events, 'duration') };
|
|
53
58
|
};
|
|
54
59
|
|
|
55
60
|
return new Stream(({ next }) => {
|
|
@@ -57,16 +62,19 @@ export class LoggingServiceImpl implements LoggingService {
|
|
|
57
62
|
const metrics: Metrics = {
|
|
58
63
|
timestamp: new Date(),
|
|
59
64
|
values: [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
],
|
|
65
|
+
getNumericalValues('dxos.echo.pipeline.control'),
|
|
66
|
+
getNumericalValues('dxos.echo.pipeline.data'),
|
|
67
|
+
].filter(Boolean) as Metrics.KeyPair[],
|
|
63
68
|
};
|
|
64
69
|
|
|
65
|
-
next(
|
|
70
|
+
next({
|
|
71
|
+
timestamp: new Date(),
|
|
72
|
+
metrics,
|
|
73
|
+
});
|
|
66
74
|
};
|
|
67
75
|
|
|
68
76
|
update();
|
|
69
|
-
const i = setInterval(update, interval);
|
|
77
|
+
const i = setInterval(update, Math.max(interval, 1_000));
|
|
70
78
|
return () => {
|
|
71
79
|
clearInterval(i);
|
|
72
80
|
};
|