@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.
Files changed (132) hide show
  1. package/dist/lib/browser/{chunk-IPWEAPT2.mjs → chunk-CRXXOI45.mjs} +5186 -6222
  2. package/dist/lib/browser/chunk-CRXXOI45.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +3 -7
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +7 -12
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/{chunk-DJIOUOAF.cjs → chunk-PZ3JJJ3K.cjs} +5137 -6167
  9. package/dist/lib/node/chunk-PZ3JJJ3K.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +46 -50
  11. package/dist/lib/node/index.cjs.map +3 -3
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node/testing/index.cjs +13 -18
  14. package/dist/lib/node/testing/index.cjs.map +3 -3
  15. package/dist/types/src/index.d.ts +0 -1
  16. package/dist/types/src/index.d.ts.map +1 -1
  17. package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
  18. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  19. package/dist/types/src/packlets/identity/authenticator.test.d.ts +2 -0
  20. package/dist/types/src/packlets/identity/authenticator.test.d.ts.map +1 -0
  21. package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
  22. package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
  23. package/dist/types/src/packlets/identity/identity-manager.d.ts +9 -25
  24. package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
  25. package/dist/types/src/packlets/identity/identity.d.ts +3 -12
  26. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  27. package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
  28. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts +1 -2
  29. package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
  30. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts +1 -2
  31. package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
  32. package/dist/types/src/packlets/invitations/invitations-handler.d.ts +8 -8
  33. package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
  34. package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
  35. package/dist/types/src/packlets/services/automerge-host.test.d.ts +2 -0
  36. package/dist/types/src/packlets/services/automerge-host.test.d.ts.map +1 -0
  37. package/dist/types/src/packlets/services/service-context.d.ts +9 -12
  38. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  39. package/dist/types/src/packlets/services/service-host.d.ts +0 -1
  40. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  41. package/dist/types/src/packlets/spaces/data-space-manager.d.ts +3 -7
  42. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  43. package/dist/types/src/packlets/spaces/data-space.d.ts +3 -5
  44. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  45. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +0 -3
  46. package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
  47. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts +1 -1
  48. package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
  49. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -35
  50. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  51. package/dist/types/src/packlets/spaces/spaces-service.d.ts +1 -1
  52. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  53. package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
  54. package/dist/types/src/packlets/testing/test-builder.d.ts +2 -1
  55. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  56. package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
  57. package/dist/types/src/version.d.ts +1 -1
  58. package/dist/types/src/version.d.ts.map +1 -1
  59. package/package.json +39 -43
  60. package/src/index.ts +0 -1
  61. package/src/packlets/devices/devices-service.test.ts +5 -4
  62. package/src/packlets/diagnostics/diagnostics-broadcast.ts +0 -1
  63. package/src/packlets/identity/{authenticator.node.test.ts → authenticator.test.ts} +3 -2
  64. package/src/packlets/identity/authenticator.ts +2 -5
  65. package/src/packlets/identity/contacts-service.ts +1 -1
  66. package/src/packlets/identity/identity-manager.test.ts +16 -31
  67. package/src/packlets/identity/identity-manager.ts +31 -47
  68. package/src/packlets/identity/identity-service.test.ts +8 -4
  69. package/src/packlets/identity/identity.test.ts +239 -130
  70. package/src/packlets/identity/identity.ts +17 -60
  71. package/src/packlets/invitations/device-invitation-protocol.test.ts +4 -7
  72. package/src/packlets/invitations/device-invitation-protocol.ts +1 -5
  73. package/src/packlets/invitations/invitation-guest-extenstion.ts +4 -8
  74. package/src/packlets/invitations/invitation-host-extension.ts +7 -8
  75. package/src/packlets/invitations/invitations-handler.test.ts +9 -16
  76. package/src/packlets/invitations/invitations-handler.ts +93 -23
  77. package/src/packlets/invitations/space-invitation-protocol.test.ts +3 -4
  78. package/src/packlets/invitations/space-invitation-protocol.ts +0 -4
  79. package/src/packlets/logging/logging.test.ts +2 -1
  80. package/src/packlets/network/network-service.test.ts +3 -2
  81. package/src/packlets/services/automerge-host.test.ts +60 -0
  82. package/src/packlets/services/service-context.test.ts +1 -3
  83. package/src/packlets/services/service-context.ts +37 -104
  84. package/src/packlets/services/service-host.test.ts +12 -8
  85. package/src/packlets/services/service-host.ts +6 -16
  86. package/src/packlets/services/service-registry.test.ts +2 -1
  87. package/src/packlets/spaces/data-space-manager.test.ts +2 -2
  88. package/src/packlets/spaces/data-space-manager.ts +7 -44
  89. package/src/packlets/spaces/data-space.ts +6 -37
  90. package/src/packlets/spaces/edge-feed-replicator.ts +22 -80
  91. package/src/packlets/spaces/epoch-migrations.ts +2 -2
  92. package/src/packlets/spaces/notarization-plugin.test.ts +7 -10
  93. package/src/packlets/spaces/notarization-plugin.ts +29 -196
  94. package/src/packlets/spaces/spaces-service.test.ts +9 -5
  95. package/src/packlets/spaces/spaces-service.ts +1 -6
  96. package/src/packlets/storage/storage.ts +1 -0
  97. package/src/packlets/system/system-service.test.ts +2 -1
  98. package/src/packlets/testing/test-builder.ts +4 -7
  99. package/src/packlets/worker/worker-runtime.ts +2 -2
  100. package/src/version.ts +5 -1
  101. package/dist/lib/browser/chunk-IPWEAPT2.mjs.map +0 -7
  102. package/dist/lib/node/chunk-DJIOUOAF.cjs.map +0 -7
  103. package/dist/lib/node-esm/chunk-MMU5KC57.mjs +0 -8752
  104. package/dist/lib/node-esm/chunk-MMU5KC57.mjs.map +0 -7
  105. package/dist/lib/node-esm/index.mjs +0 -420
  106. package/dist/lib/node-esm/index.mjs.map +0 -7
  107. package/dist/lib/node-esm/meta.json +0 -1
  108. package/dist/lib/node-esm/testing/index.mjs +0 -424
  109. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  110. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +0 -35
  111. package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +0 -1
  112. package/dist/types/src/packlets/agents/edge-agent-service.d.ts +0 -10
  113. package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +0 -1
  114. package/dist/types/src/packlets/agents/index.d.ts +0 -3
  115. package/dist/types/src/packlets/agents/index.d.ts.map +0 -1
  116. package/dist/types/src/packlets/identity/authenticator.node.test.d.ts +0 -2
  117. package/dist/types/src/packlets/identity/authenticator.node.test.d.ts.map +0 -1
  118. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +0 -30
  119. package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +0 -1
  120. package/dist/types/src/packlets/invitations/invitation-state.d.ts +0 -19
  121. package/dist/types/src/packlets/invitations/invitation-state.d.ts.map +0 -1
  122. package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts +0 -2
  123. package/dist/types/src/packlets/spaces/edge-feed-replicator.test.d.ts.map +0 -1
  124. package/dist/types/src/testing/setup.d.ts +0 -3
  125. package/dist/types/src/testing/setup.d.ts.map +0 -1
  126. package/src/packlets/agents/edge-agent-manager.ts +0 -163
  127. package/src/packlets/agents/edge-agent-service.ts +0 -42
  128. package/src/packlets/agents/index.ts +0 -6
  129. package/src/packlets/invitations/edge-invitation-handler.ts +0 -185
  130. package/src/packlets/invitations/invitation-state.ts +0 -111
  131. package/src/packlets/spaces/edge-feed-replicator.test.ts +0 -252
  132. package/src/testing/setup.ts +0 -11
@@ -2,13 +2,14 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { describe, expect, test } from 'vitest';
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 -- auth success', { key: credential.issuer });
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 { type SpaceManager } from '@dxos/echo-pipeline';
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 { describe, expect, test, onTestFinished } from 'vitest';
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
- onTestFinished(() => feedStore.close());
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({ metadataStore, keyring, feedStore, spaceManager });
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
- onTestFinished(() => identityManager.close());
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
- onTestFinished(() => identityManager.close());
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
- const { identity: identity2, identityRecord } = await peer2.identityManager.prepareIdentity({
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 IdentityManagerParams = {
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 readonly _metadataStore: MetadataStore;
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(params: IdentityManagerParams) {
99
- this._metadataStore = params.metadataStore;
100
- this._keyring = params.keyring;
101
- this._feedStore = params.feedStore;
102
- this._spaceManager = params.spaceManager;
103
- this._edgeConnection = params.edgeConnection;
104
- this._edgeFeatures = params.edgeFeatures;
105
- this._devicePresenceAnnounceInterval = params.devicePresenceAnnounceInterval ?? DEVICE_PRESENCE_ANNOUNCE_INTERVAL;
106
- this._devicePresenceOfflineTimeout = params.devicePresenceOfflineTimeout ?? DEVICE_PRESENCE_OFFLINE_TIMEOUT;
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
- * Prepare an identity object as the first step of acceptIdentity flow.
235
+ * Accept an existing identity. Expects its device key to be authorized (now or later).
242
236
  */
243
- async prepareIdentity(params: JoinIdentityParams) {
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: this._identity!.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
- ...profile,
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 { afterEach, onTestFinished, beforeEach, describe, expect, test } from 'vitest';
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({})).rejects.toThrowError('Identity already exists');
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
- onTestFinished(() => query.close());
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
- onTestFinished(() => query.close());
85
+ afterTest(() => query.close());
82
86
  expect(await result.wait()).to.be.undefined;
83
87
 
84
88
  result = new Trigger<Identity | undefined>();