@dxos/client-services 0.6.13-main.ed424a1 → 0.6.13
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-IPWEAPT2.mjs → chunk-CRXXOI45.mjs} +5186 -6222
- package/dist/lib/browser/chunk-CRXXOI45.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3 -7
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +7 -12
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-DJIOUOAF.cjs → chunk-PZ3JJJ3K.cjs} +5137 -6167
- package/dist/lib/node/chunk-PZ3JJJ3K.cjs.map +7 -0
- package/dist/lib/node/index.cjs +46 -50
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +13 -18
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.test.d.ts +2 -0
- package/dist/types/src/packlets/identity/authenticator.test.d.ts.map +1 -0
- package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +9 -25
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +3 -12
- 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-guest-extenstion.d.ts +1 -2
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts +1 -2
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +8 -8
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/services/automerge-host.test.d.ts +2 -0
- package/dist/types/src/packlets/services/automerge-host.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts +9 -12
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +0 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +3 -7
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +3 -5
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +0 -3
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -35
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +2 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/package.json +39 -43
- package/src/index.ts +0 -1
- package/src/packlets/devices/devices-service.test.ts +5 -4
- package/src/packlets/diagnostics/diagnostics-broadcast.ts +0 -1
- package/src/packlets/identity/{authenticator.node.test.ts → authenticator.test.ts} +3 -2
- package/src/packlets/identity/authenticator.ts +2 -5
- package/src/packlets/identity/contacts-service.ts +1 -1
- package/src/packlets/identity/identity-manager.test.ts +16 -31
- package/src/packlets/identity/identity-manager.ts +31 -47
- package/src/packlets/identity/identity-service.test.ts +8 -4
- package/src/packlets/identity/identity.test.ts +239 -130
- package/src/packlets/identity/identity.ts +17 -60
- package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -7
- package/src/packlets/invitations/device-invitation-protocol.ts +1 -5
- package/src/packlets/invitations/invitation-guest-extenstion.ts +4 -8
- package/src/packlets/invitations/invitation-host-extension.ts +7 -8
- package/src/packlets/invitations/invitations-handler.test.ts +9 -16
- package/src/packlets/invitations/invitations-handler.ts +93 -23
- package/src/packlets/invitations/space-invitation-protocol.test.ts +3 -4
- package/src/packlets/invitations/space-invitation-protocol.ts +0 -4
- package/src/packlets/logging/logging.test.ts +2 -1
- package/src/packlets/network/network-service.test.ts +3 -2
- package/src/packlets/services/automerge-host.test.ts +60 -0
- package/src/packlets/services/service-context.test.ts +1 -3
- package/src/packlets/services/service-context.ts +37 -104
- package/src/packlets/services/service-host.test.ts +12 -8
- package/src/packlets/services/service-host.ts +6 -16
- package/src/packlets/services/service-registry.test.ts +2 -1
- package/src/packlets/spaces/data-space-manager.test.ts +2 -2
- package/src/packlets/spaces/data-space-manager.ts +7 -44
- package/src/packlets/spaces/data-space.ts +6 -37
- package/src/packlets/spaces/edge-feed-replicator.ts +22 -80
- package/src/packlets/spaces/epoch-migrations.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.test.ts +7 -10
- package/src/packlets/spaces/notarization-plugin.ts +29 -196
- package/src/packlets/spaces/spaces-service.test.ts +9 -5
- package/src/packlets/spaces/spaces-service.ts +1 -6
- package/src/packlets/storage/storage.ts +1 -0
- package/src/packlets/system/system-service.test.ts +2 -1
- package/src/packlets/testing/test-builder.ts +4 -7
- package/src/packlets/worker/worker-runtime.ts +2 -2
- package/src/version.ts +5 -1
- package/dist/lib/browser/chunk-IPWEAPT2.mjs.map +0 -7
- package/dist/lib/node/chunk-DJIOUOAF.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-MMU5KC57.mjs +0 -8752
- package/dist/lib/node-esm/chunk-MMU5KC57.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -420
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -424
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +0 -35
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +0 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +0 -10
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +0 -1
- package/dist/types/src/packlets/agents/index.d.ts +0 -3
- package/dist/types/src/packlets/agents/index.d.ts.map +0 -1
- package/dist/types/src/packlets/identity/authenticator.node.test.d.ts +0 -2
- package/dist/types/src/packlets/identity/authenticator.node.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +0 -30
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/invitation-state.d.ts +0 -19
- package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +0 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts +0 -2
- package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts.map +0 -1
- package/dist/types/src/testing/setup.d.ts +0 -3
- package/dist/types/src/testing/setup.d.ts.map +0 -1
- package/src/packlets/agents/edge-agent-manager.ts +0 -163
- package/src/packlets/agents/edge-agent-service.ts +0 -42
- package/src/packlets/agents/index.ts +0 -6
- package/src/packlets/invitations/edge-invitation-handler.ts +0 -185
- package/src/packlets/invitations/invitation-state.ts +0 -111
- package/src/packlets/spaces/edge-feed-replicator.test.ts +0 -252
- package/src/testing/setup.ts +0 -11
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import expect from 'expect';
|
|
6
6
|
|
|
7
7
|
import { Event } from '@dxos/async';
|
|
8
8
|
import { createCredentialSignerWithKey } from '@dxos/credentials';
|
|
9
9
|
import { invariant } from '@dxos/invariant';
|
|
10
10
|
import { Keyring } from '@dxos/keyring';
|
|
11
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
|
+
import { describe, test } from '@dxos/test';
|
|
12
13
|
import { ComplexSet } from '@dxos/util';
|
|
13
14
|
|
|
14
15
|
import { createAuthProvider, TrustedKeySetAuthVerifier } from './authenticator';
|
|
@@ -29,5 +30,5 @@ describe('identity/authenticator', () => {
|
|
|
29
30
|
const credential = await authProvider(nonce);
|
|
30
31
|
invariant(credential);
|
|
31
32
|
expect(await authVerifier.verifier(nonce, credential)).toBeTruthy();
|
|
32
|
-
});
|
|
33
|
+
}).onlyEnvironments('nodejs');
|
|
33
34
|
});
|
|
@@ -67,7 +67,7 @@ export class TrustedKeySetAuthVerifier {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
if (this._isTrustedKey(credential.issuer)) {
|
|
70
|
-
log('key is trusted
|
|
70
|
+
log('key is not currently in trusted set, waiting...', { key: credential.issuer });
|
|
71
71
|
return true;
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -81,10 +81,7 @@ export class TrustedKeySetAuthVerifier {
|
|
|
81
81
|
log('auth success', { key: credential.issuer });
|
|
82
82
|
trigger.wake(true);
|
|
83
83
|
} else {
|
|
84
|
-
log('key is not currently in trusted set, waiting...', {
|
|
85
|
-
key: credential.issuer,
|
|
86
|
-
trusted: [...this._params.trustedKeysProvider()],
|
|
87
|
-
});
|
|
84
|
+
log('key is not currently in trusted set, waiting...', { key: credential.issuer });
|
|
88
85
|
}
|
|
89
86
|
});
|
|
90
87
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { EventSubscriptions, scheduleTask, UpdateScheduler } from '@dxos/async';
|
|
6
6
|
import { Stream } from '@dxos/codec-protobuf';
|
|
7
7
|
import { type MemberInfo } from '@dxos/credentials';
|
|
8
|
-
import {
|
|
8
|
+
import type { SpaceManager } from '@dxos/echo-pipeline';
|
|
9
9
|
import { PublicKey } from '@dxos/keys';
|
|
10
10
|
import { type Contact, type ContactBook, type ContactsService } from '@dxos/protocols/proto/dxos/client/services';
|
|
11
11
|
import { ComplexMap, ComplexSet } from '@dxos/util';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { expect } from 'chai';
|
|
6
6
|
|
|
7
7
|
import { Context } from '@dxos/context';
|
|
8
8
|
import { valueEncoding, MetadataStore, SpaceManager, AuthStatus } from '@dxos/echo-pipeline';
|
|
@@ -13,6 +13,7 @@ import { MemoryTransportFactory, SwarmNetworkManager } from '@dxos/network-manag
|
|
|
13
13
|
import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
14
14
|
import { createStorage, type Storage, StorageType } from '@dxos/random-access-storage';
|
|
15
15
|
import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
16
|
+
import { describe, test, afterTest } from '@dxos/test';
|
|
16
17
|
|
|
17
18
|
import { IdentityManager } from './identity-manager';
|
|
18
19
|
|
|
@@ -38,7 +39,7 @@ describe('identity/identity-manager', () => {
|
|
|
38
39
|
}),
|
|
39
40
|
});
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
afterTest(() => feedStore.close());
|
|
42
43
|
|
|
43
44
|
const networkManager = new SwarmNetworkManager({
|
|
44
45
|
signalManager: new MemorySignalManager(signalContext),
|
|
@@ -50,10 +51,9 @@ describe('identity/identity-manager', () => {
|
|
|
50
51
|
blobStore,
|
|
51
52
|
metadataStore,
|
|
52
53
|
});
|
|
53
|
-
const identityManager = new IdentityManager(
|
|
54
|
+
const identityManager = new IdentityManager(metadataStore, keyring, feedStore, spaceManager);
|
|
54
55
|
|
|
55
56
|
return {
|
|
56
|
-
networkManager,
|
|
57
57
|
metadataStore,
|
|
58
58
|
identityManager,
|
|
59
59
|
feedStore,
|
|
@@ -64,7 +64,7 @@ describe('identity/identity-manager', () => {
|
|
|
64
64
|
test('creates identity', async () => {
|
|
65
65
|
const { identityManager } = await setupPeer();
|
|
66
66
|
await identityManager.open(new Context());
|
|
67
|
-
|
|
67
|
+
afterTest(() => identityManager.close());
|
|
68
68
|
|
|
69
69
|
const identity = await identityManager.createIdentity();
|
|
70
70
|
expect(identity).to.exist;
|
|
@@ -95,7 +95,7 @@ describe('identity/identity-manager', () => {
|
|
|
95
95
|
test('update profile', async () => {
|
|
96
96
|
const { identityManager } = await setupPeer();
|
|
97
97
|
await identityManager.open(new Context());
|
|
98
|
-
|
|
98
|
+
afterTest(() => identityManager.close());
|
|
99
99
|
|
|
100
100
|
const identity = await identityManager.createIdentity();
|
|
101
101
|
expect(identity.profileDocument?.displayName).to.be.undefined;
|
|
@@ -108,11 +108,6 @@ describe('identity/identity-manager', () => {
|
|
|
108
108
|
|
|
109
109
|
const peer1 = await setupPeer({ signalContext });
|
|
110
110
|
const identity1 = await peer1.identityManager.createIdentity();
|
|
111
|
-
peer1.networkManager.setPeerInfo({
|
|
112
|
-
peerKey: identity1.deviceKey.toHex(),
|
|
113
|
-
identityKey: identity1.identityKey.toHex(),
|
|
114
|
-
});
|
|
115
|
-
await identity1.joinNetwork();
|
|
116
111
|
|
|
117
112
|
const peer2 = await setupPeer({ signalContext });
|
|
118
113
|
|
|
@@ -120,38 +115,28 @@ describe('identity/identity-manager', () => {
|
|
|
120
115
|
const controlFeedKey = await peer2.keyring.createKey();
|
|
121
116
|
const dataFeedKey = await peer2.keyring.createKey();
|
|
122
117
|
|
|
123
|
-
const credential = await identity1.getIdentityCredentialSigner().createCredential({
|
|
124
|
-
subject: deviceKey,
|
|
125
|
-
assertion: {
|
|
126
|
-
'@type': 'dxos.halo.credentials.AuthorizedDevice',
|
|
127
|
-
identityKey: identity1.identityKey,
|
|
128
|
-
deviceKey,
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
|
|
132
118
|
await identity1.controlPipeline.writer.write({
|
|
133
119
|
credential: {
|
|
134
|
-
credential
|
|
120
|
+
credential: await identity1.getIdentityCredentialSigner().createCredential({
|
|
121
|
+
subject: deviceKey,
|
|
122
|
+
assertion: {
|
|
123
|
+
'@type': 'dxos.halo.credentials.AuthorizedDevice',
|
|
124
|
+
identityKey: identity1.identityKey,
|
|
125
|
+
deviceKey,
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
135
128
|
},
|
|
136
129
|
});
|
|
137
130
|
|
|
138
|
-
|
|
131
|
+
// Identity2 is not yet ready at this point. Peer1 needs to admit peer2 device key and feed keys.
|
|
132
|
+
const identity2 = await peer2.identityManager.acceptIdentity({
|
|
139
133
|
identityKey: identity1.identityKey,
|
|
140
134
|
deviceKey,
|
|
141
135
|
haloSpaceKey: identity1.haloSpaceKey,
|
|
142
136
|
haloGenesisFeedKey: identity1.haloGenesisFeedKey,
|
|
143
137
|
controlFeedKey,
|
|
144
138
|
dataFeedKey,
|
|
145
|
-
authorizedDeviceCredential: credential,
|
|
146
|
-
});
|
|
147
|
-
peer2.networkManager.setPeerInfo({
|
|
148
|
-
peerKey: identity2.deviceKey.toHex(),
|
|
149
|
-
identityKey: identity2.identityKey.toHex(),
|
|
150
139
|
});
|
|
151
|
-
await identity2.joinNetwork();
|
|
152
|
-
|
|
153
|
-
// Identity2 is not yet ready at this point. Peer1 needs to admit peer2 device key and feed keys.
|
|
154
|
-
await peer2.identityManager.acceptIdentity(identity2, identityRecord);
|
|
155
140
|
|
|
156
141
|
// TODO(dmaretskyi): We'd also need to admit device2's feeds otherwise messages from them won't be processed by the pipeline.
|
|
157
142
|
// This would mean that peer2 has replicated it's device credential chain from peer1 and is ready to issue credentials.
|
|
@@ -7,7 +7,6 @@ import { Event } from '@dxos/async';
|
|
|
7
7
|
import { Context } from '@dxos/context';
|
|
8
8
|
import { createCredentialSignerWithKey, CredentialGenerator } from '@dxos/credentials';
|
|
9
9
|
import { type MetadataStore, type SpaceManager, type SwarmIdentity } from '@dxos/echo-pipeline';
|
|
10
|
-
import { type EdgeConnection } from '@dxos/edge-client';
|
|
11
10
|
import { type FeedStore } from '@dxos/feed-store';
|
|
12
11
|
import { invariant } from '@dxos/invariant';
|
|
13
12
|
import { type Keyring } from '@dxos/keyring';
|
|
@@ -15,7 +14,6 @@ import { PublicKey } from '@dxos/keys';
|
|
|
15
14
|
import { log } from '@dxos/log';
|
|
16
15
|
import { trace } from '@dxos/protocols';
|
|
17
16
|
import { Device, DeviceKind } from '@dxos/protocols/proto/dxos/client/services';
|
|
18
|
-
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
19
17
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
20
18
|
import { type IdentityRecord, type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
21
19
|
import {
|
|
@@ -23,7 +21,6 @@ import {
|
|
|
23
21
|
type DeviceProfileDocument,
|
|
24
22
|
DeviceType,
|
|
25
23
|
type ProfileDocument,
|
|
26
|
-
type Credential,
|
|
27
24
|
} from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
28
25
|
import { Gossip, Presence } from '@dxos/teleport-extension-gossip';
|
|
29
26
|
import { Timeframe } from '@dxos/timeframe';
|
|
@@ -50,7 +47,6 @@ export type JoinIdentityParams = {
|
|
|
50
47
|
haloGenesisFeedKey: PublicKey;
|
|
51
48
|
controlFeedKey: PublicKey;
|
|
52
49
|
dataFeedKey: PublicKey;
|
|
53
|
-
authorizedDeviceCredential: Credential;
|
|
54
50
|
|
|
55
51
|
/**
|
|
56
52
|
* Latest known timeframe for the control pipeline.
|
|
@@ -67,13 +63,7 @@ export type CreateIdentityOptions = {
|
|
|
67
63
|
deviceProfile?: DeviceProfileDocument;
|
|
68
64
|
};
|
|
69
65
|
|
|
70
|
-
export type
|
|
71
|
-
metadataStore: MetadataStore;
|
|
72
|
-
keyring: Keyring;
|
|
73
|
-
feedStore: FeedStore<FeedMessage>;
|
|
74
|
-
spaceManager: SpaceManager;
|
|
75
|
-
edgeConnection?: EdgeConnection;
|
|
76
|
-
edgeFeatures?: Runtime.Client.EdgeFeatures;
|
|
66
|
+
export type IdentityManagerRuntimeParams = {
|
|
77
67
|
devicePresenceAnnounceInterval?: number;
|
|
78
68
|
devicePresenceOfflineTimeout?: number;
|
|
79
69
|
};
|
|
@@ -83,27 +73,28 @@ export type IdentityManagerParams = {
|
|
|
83
73
|
export class IdentityManager {
|
|
84
74
|
readonly stateUpdate = new Event();
|
|
85
75
|
|
|
86
|
-
private
|
|
87
|
-
private readonly _keyring: Keyring;
|
|
88
|
-
private readonly _feedStore: FeedStore<FeedMessage>;
|
|
89
|
-
private readonly _spaceManager: SpaceManager;
|
|
76
|
+
private _identity?: Identity;
|
|
90
77
|
private readonly _devicePresenceAnnounceInterval: number;
|
|
91
78
|
private readonly _devicePresenceOfflineTimeout: number;
|
|
92
|
-
private readonly _edgeConnection: EdgeConnection | undefined;
|
|
93
|
-
private readonly _edgeFeatures: Runtime.Client.EdgeFeatures | undefined;
|
|
94
|
-
|
|
95
|
-
private _identity?: Identity;
|
|
96
79
|
|
|
80
|
+
// TODO(burdon): IdentityManagerParams.
|
|
97
81
|
// TODO(dmaretskyi): Perhaps this should take/generate the peerKey outside of an initialized identity.
|
|
98
|
-
constructor(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
82
|
+
constructor(
|
|
83
|
+
private readonly _metadataStore: MetadataStore,
|
|
84
|
+
private readonly _keyring: Keyring,
|
|
85
|
+
private readonly _feedStore: FeedStore<FeedMessage>,
|
|
86
|
+
private readonly _spaceManager: SpaceManager,
|
|
87
|
+
params?: IdentityManagerRuntimeParams,
|
|
88
|
+
private readonly _callbacks?: {
|
|
89
|
+
onIdentityConstruction?: (identity: Identity) => void;
|
|
90
|
+
},
|
|
91
|
+
) {
|
|
92
|
+
const {
|
|
93
|
+
devicePresenceAnnounceInterval = DEVICE_PRESENCE_ANNOUNCE_INTERVAL,
|
|
94
|
+
devicePresenceOfflineTimeout = DEVICE_PRESENCE_OFFLINE_TIMEOUT,
|
|
95
|
+
} = params ?? {};
|
|
96
|
+
this._devicePresenceAnnounceInterval = devicePresenceAnnounceInterval;
|
|
97
|
+
this._devicePresenceOfflineTimeout = devicePresenceOfflineTimeout;
|
|
107
98
|
}
|
|
108
99
|
|
|
109
100
|
get identity() {
|
|
@@ -193,6 +184,10 @@ export class IdentityManager {
|
|
|
193
184
|
}
|
|
194
185
|
}
|
|
195
186
|
|
|
187
|
+
// TODO(burdon): ???
|
|
188
|
+
// await this._keyring.deleteKey(identityRecord.identity_key);
|
|
189
|
+
// await this._keyring.deleteKey(identityRecord.halo_space.space_key);
|
|
190
|
+
|
|
196
191
|
await this._metadataStore.setIdentityRecord(identityRecord);
|
|
197
192
|
this._identity = identity;
|
|
198
193
|
await this._identity.ready();
|
|
@@ -207,7 +202,6 @@ export class IdentityManager {
|
|
|
207
202
|
deviceKey: identity.deviceKey,
|
|
208
203
|
profile: identity.profileDocument,
|
|
209
204
|
});
|
|
210
|
-
|
|
211
205
|
return identity;
|
|
212
206
|
}
|
|
213
207
|
|
|
@@ -238,9 +232,9 @@ export class IdentityManager {
|
|
|
238
232
|
}
|
|
239
233
|
|
|
240
234
|
/**
|
|
241
|
-
*
|
|
235
|
+
* Accept an existing identity. Expects its device key to be authorized (now or later).
|
|
242
236
|
*/
|
|
243
|
-
async
|
|
237
|
+
async acceptIdentity(params: JoinIdentityParams) {
|
|
244
238
|
log('accepting identity', { params });
|
|
245
239
|
invariant(!this._identity, 'Identity already exists.');
|
|
246
240
|
|
|
@@ -255,33 +249,24 @@ export class IdentityManager {
|
|
|
255
249
|
controlTimeframe: params.controlTimeframe,
|
|
256
250
|
},
|
|
257
251
|
};
|
|
252
|
+
|
|
258
253
|
const identity = await this._constructIdentity(identityRecord);
|
|
259
254
|
await identity.open(new Context());
|
|
260
|
-
return { identity, identityRecord };
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Accept an existing identity. Expects its device key to be authorized (now or later).
|
|
265
|
-
*/
|
|
266
|
-
public async acceptIdentity(identity: Identity, identityRecord: IdentityRecord, profile?: DeviceProfileDocument) {
|
|
267
255
|
this._identity = identity;
|
|
268
|
-
|
|
269
|
-
// Identity becomes ready after device chain is replicated. Wait for it before storing the record.
|
|
270
|
-
await this._identity.ready();
|
|
271
256
|
await this._metadataStore.setIdentityRecord(identityRecord);
|
|
272
|
-
|
|
257
|
+
await this._identity.ready();
|
|
273
258
|
log.trace('dxos.halo.identity', {
|
|
274
|
-
identityKey:
|
|
259
|
+
identityKey: identityRecord.identityKey,
|
|
275
260
|
displayName: this._identity.profileDocument?.displayName,
|
|
276
261
|
});
|
|
277
262
|
|
|
278
263
|
await this.updateDeviceProfile({
|
|
279
264
|
...this.createDefaultDeviceProfile(),
|
|
280
|
-
...
|
|
265
|
+
...params.deviceProfile,
|
|
281
266
|
});
|
|
282
267
|
this.stateUpdate.emit();
|
|
283
|
-
|
|
284
268
|
log('accepted identity', { identityKey: identity.identityKey, deviceKey: identity.deviceKey });
|
|
269
|
+
return identity;
|
|
285
270
|
}
|
|
286
271
|
|
|
287
272
|
/**
|
|
@@ -375,10 +360,9 @@ export class IdentityManager {
|
|
|
375
360
|
signer: this._keyring,
|
|
376
361
|
identityKey: identityRecord.identityKey,
|
|
377
362
|
deviceKey: identityRecord.deviceKey,
|
|
378
|
-
edgeConnection: this._edgeConnection,
|
|
379
|
-
edgeFeatures: this._edgeFeatures,
|
|
380
363
|
});
|
|
381
364
|
log('done', { identityKey: identityRecord.identityKey });
|
|
365
|
+
this._callbacks?.onIdentityConstruction?.(identity);
|
|
382
366
|
|
|
383
367
|
// TODO(mykola): Set new timeframe on a write to a feed.
|
|
384
368
|
if (identityRecord.haloSpace.controlTimeframe) {
|
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import chai, { expect } from 'chai';
|
|
6
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
6
7
|
|
|
7
8
|
import { Trigger } from '@dxos/async';
|
|
8
9
|
import { Context } from '@dxos/context';
|
|
9
10
|
import { PublicKey } from '@dxos/keys';
|
|
10
11
|
import { type Identity, type IdentityService } from '@dxos/protocols/proto/dxos/client/services';
|
|
12
|
+
import { afterEach, afterTest, beforeEach, describe, test } from '@dxos/test';
|
|
11
13
|
|
|
12
14
|
import { IdentityServiceImpl } from './identity-service';
|
|
13
15
|
import { type ServiceContext } from '../services';
|
|
14
16
|
import { createServiceContext } from '../testing';
|
|
15
17
|
|
|
18
|
+
chai.use(chaiAsPromised);
|
|
19
|
+
|
|
16
20
|
describe('IdentityService', () => {
|
|
17
21
|
let serviceContext: ServiceContext;
|
|
18
22
|
let identityService: IdentityService;
|
|
@@ -45,7 +49,7 @@ describe('IdentityService', () => {
|
|
|
45
49
|
|
|
46
50
|
test('fails to create identity if one already exists', async () => {
|
|
47
51
|
await identityService.createIdentity({});
|
|
48
|
-
await expect(identityService.createIdentity({})).
|
|
52
|
+
await expect(identityService.createIdentity({})).to.be.rejectedWith('Identity already exists');
|
|
49
53
|
});
|
|
50
54
|
});
|
|
51
55
|
|
|
@@ -68,7 +72,7 @@ describe('IdentityService', () => {
|
|
|
68
72
|
query.subscribe(({ identity }) => {
|
|
69
73
|
result.wake(identity);
|
|
70
74
|
});
|
|
71
|
-
|
|
75
|
+
afterTest(() => query.close());
|
|
72
76
|
expect(await result.wait()).to.be.undefined;
|
|
73
77
|
});
|
|
74
78
|
|
|
@@ -78,7 +82,7 @@ describe('IdentityService', () => {
|
|
|
78
82
|
query.subscribe(({ identity }) => {
|
|
79
83
|
result.wake(identity);
|
|
80
84
|
});
|
|
81
|
-
|
|
85
|
+
afterTest(() => query.close());
|
|
82
86
|
expect(await result.wait()).to.be.undefined;
|
|
83
87
|
|
|
84
88
|
result = new Trigger<Identity | undefined>();
|