@dxos/client-services 0.1.26 → 0.1.27-next.a0dff21
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-R2FEBB66.mjs → chunk-OTSGRZZI.mjs} +796 -579
- package/dist/lib/browser/chunk-OTSGRZZI.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +19 -15
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +46 -46
- package/dist/lib/browser/packlets/testing/index.mjs.map +4 -4
- package/dist/lib/node/index.cjs +864 -641
- 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 +753 -631
- package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/deprecated/index.d.ts +0 -3
- package/dist/types/src/packlets/deprecated/index.d.ts.map +1 -1
- package/dist/types/src/packlets/{identity/devices-service-impl.d.ts → devices/devices-service.d.ts} +4 -3
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -0
- package/dist/types/src/packlets/devices/index.d.ts +2 -0
- package/dist/types/src/packlets/devices/index.d.ts.map +1 -0
- package/dist/types/src/packlets/identity/authenticator.d.ts +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +2 -2
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +14 -0
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -0
- package/dist/types/src/packlets/identity/identity.d.ts +2 -2
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/index.d.ts +1 -0
- package/dist/types/src/packlets/identity/index.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/{halo-invitations-handler.d.ts → device-invitations-handler.d.ts} +5 -5
- package/dist/types/src/packlets/invitations/device-invitations-handler.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts +2 -0
- package/dist/types/src/packlets/invitations/device-invitations-handler.test.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/{halo-invitations-proxy.d.ts → device-invitations-proxy.d.ts} +2 -2
- package/dist/types/src/packlets/invitations/device-invitations-proxy.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/{halo-invitations-service.d.ts → device-invitations-service.d.ts} +2 -2
- package/dist/types/src/packlets/invitations/device-invitations-service.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts +2 -0
- package/dist/types/src/packlets/invitations/device-invitations-service.test.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/index.d.ts +3 -3
- package/dist/types/src/packlets/invitations/index.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +6 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts +1 -1
- package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/services/index.d.ts +0 -1
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +3 -3
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-definitions.d.ts +5 -7
- package/dist/types/src/packlets/services/service-definitions.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +1 -0
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +12 -5
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/system/index.d.ts +2 -0
- package/dist/types/src/packlets/system/index.d.ts.map +1 -0
- package/dist/types/src/packlets/system/system-service.d.ts +28 -0
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -0
- package/dist/types/src/packlets/system/system-service.test.d.ts +2 -0
- package/dist/types/src/packlets/system/system-service.test.d.ts.map +1 -0
- package/dist/types/src/packlets/testing/index.d.ts +1 -1
- package/dist/types/src/packlets/testing/index.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts +11 -4
- package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts +6 -1
- package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/index.d.ts +2 -0
- package/dist/types/src/packlets/vault/index.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/services.d.ts +9 -1
- package/dist/types/src/packlets/vault/services.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/shell-controller.d.ts +18 -0
- package/dist/types/src/packlets/vault/shell-controller.d.ts.map +1 -0
- package/dist/types/src/packlets/vault/shell-runtime.d.ts +45 -0
- package/dist/types/src/packlets/vault/shell-runtime.d.ts.map +1 -0
- package/dist/types/src/packlets/vault/worker-runtime.d.ts +2 -1
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/vault/worker-session.d.ts +4 -1
- package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
- package/package.json +29 -28
- package/src/index.ts +0 -1
- package/src/packlets/deprecated/index.ts +0 -3
- package/src/packlets/{identity/devices-service-impl.ts → devices/devices-service.ts} +10 -8
- package/src/packlets/devices/index.ts +5 -0
- package/src/packlets/devtools/spaces.ts +1 -1
- package/src/packlets/identity/authenticator.ts +1 -1
- package/src/packlets/identity/identity-manager.test.ts +1 -1
- package/src/packlets/identity/identity-manager.ts +2 -2
- package/src/packlets/identity/identity-service.ts +67 -0
- package/src/packlets/identity/identity.test.ts +1 -1
- package/src/packlets/identity/identity.ts +1 -1
- package/src/packlets/identity/index.ts +1 -0
- package/src/packlets/invitations/{halo-invitations-handler.test.ts → device-invitations-handler.test.ts} +2 -2
- package/src/packlets/invitations/{halo-invitations-handler.ts → device-invitations-handler.ts} +4 -4
- package/src/packlets/invitations/{halo-invitations-proxy.ts → device-invitations-proxy.ts} +1 -1
- package/src/packlets/invitations/{halo-invitations-service.test.ts → device-invitations-service.test.ts} +10 -10
- package/src/packlets/invitations/{halo-invitations-service.ts → device-invitations-service.ts} +1 -1
- package/src/packlets/invitations/index.ts +3 -3
- package/src/packlets/invitations/invitations-handler.ts +6 -0
- package/src/packlets/invitations/invitations-service.ts +2 -2
- package/src/packlets/invitations/space-invitations-handler.test.ts +1 -1
- package/src/packlets/invitations/space-invitations-handler.ts +55 -20
- package/src/packlets/services/index.ts +0 -1
- package/src/packlets/services/service-context.test.ts +3 -3
- package/src/packlets/services/service-context.ts +5 -5
- package/src/packlets/services/service-definitions.ts +14 -14
- package/src/packlets/services/service-host.test.ts +9 -9
- package/src/packlets/services/service-host.ts +40 -25
- package/src/packlets/spaces/data-space-manager.test.ts +1 -1
- package/src/packlets/spaces/data-space-manager.ts +4 -4
- package/src/packlets/spaces/data-space.ts +3 -3
- package/src/packlets/spaces/spaces-service.ts +93 -11
- package/src/packlets/system/index.ts +5 -0
- package/src/packlets/system/system-service.test.ts +80 -0
- package/src/packlets/system/system-service.ts +70 -0
- package/src/packlets/testing/index.ts +1 -1
- package/src/packlets/testing/test-builder.ts +3 -3
- package/src/packlets/vault/iframe-host-runtime.ts +28 -10
- package/src/packlets/vault/iframe-proxy-runtime.ts +16 -1
- package/src/packlets/vault/index.ts +2 -0
- package/src/packlets/vault/services.ts +17 -1
- package/src/packlets/vault/shell-controller.ts +56 -0
- package/src/packlets/vault/shell-runtime.ts +121 -0
- package/src/packlets/vault/worker-runtime.ts +3 -1
- package/src/packlets/vault/worker-session.ts +28 -19
- package/dist/lib/browser/chunk-R2FEBB66.mjs.map +0 -7
- package/dist/types/src/packlets/deprecated/invitations.d.ts +0 -47
- package/dist/types/src/packlets/deprecated/invitations.d.ts.map +0 -1
- package/dist/types/src/packlets/deprecated/profile.d.ts +0 -18
- package/dist/types/src/packlets/deprecated/profile.d.ts.map +0 -1
- package/dist/types/src/packlets/deprecated/space.d.ts +0 -23
- package/dist/types/src/packlets/deprecated/space.d.ts.map +0 -1
- package/dist/types/src/packlets/deprecated/system.d.ts +0 -24
- package/dist/types/src/packlets/deprecated/system.d.ts.map +0 -1
- package/dist/types/src/packlets/identity/devices-service-impl.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/halo-invitations-handler.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/halo-invitations-handler.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/halo-invitations-handler.test.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/halo-invitations-proxy.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/halo-invitations-service.d.ts.map +0 -1
- package/dist/types/src/packlets/invitations/halo-invitations-service.test.d.ts +0 -2
- package/dist/types/src/packlets/invitations/halo-invitations-service.test.d.ts.map +0 -1
- package/dist/types/src/packlets/services/signer.d.ts +0 -6
- package/dist/types/src/packlets/services/signer.d.ts.map +0 -1
- package/src/packlets/deprecated/invitations.ts +0 -63
- package/src/packlets/deprecated/profile.ts +0 -85
- package/src/packlets/deprecated/space.ts +0 -258
- package/src/packlets/deprecated/system.ts +0 -48
- package/src/packlets/services/signer.ts +0 -11
|
@@ -8,20 +8,20 @@ import waitForExpect from 'wait-for-expect';
|
|
|
8
8
|
|
|
9
9
|
import { asyncChain, Trigger } from '@dxos/async';
|
|
10
10
|
import { raise } from '@dxos/debug';
|
|
11
|
-
import { Invitation,
|
|
11
|
+
import { Invitation, DeviceInvitationsService } from '@dxos/protocols/proto/dxos/client/services';
|
|
12
12
|
import { describe, test, afterTest } from '@dxos/test';
|
|
13
13
|
|
|
14
14
|
import { ServiceContext } from '../services';
|
|
15
15
|
import { createPeers } from '../testing';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { DeviceInvitationsProxy } from './device-invitations-proxy';
|
|
17
|
+
import { DeviceInvitationsServiceImpl } from './device-invitations-service';
|
|
18
18
|
|
|
19
19
|
const closeAfterTest = async (peer: ServiceContext) => {
|
|
20
20
|
afterTest(() => peer.close());
|
|
21
21
|
return peer;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
describe('services/
|
|
24
|
+
describe('services/device-invitation-service', () => {
|
|
25
25
|
test('creates identity and invites peer', async () => {
|
|
26
26
|
const [host, guest] = await asyncChain<ServiceContext>([closeAfterTest])(createPeers(2));
|
|
27
27
|
|
|
@@ -29,14 +29,14 @@ describe('services/halo-invitation-service', () => {
|
|
|
29
29
|
expect(host.identityManager.identity!.authorizedDeviceKeys.size).to.eq(1);
|
|
30
30
|
|
|
31
31
|
// prettier-ignore
|
|
32
|
-
const service1:
|
|
32
|
+
const service1: DeviceInvitationsService = new DeviceInvitationsServiceImpl(
|
|
33
33
|
host.identityManager,
|
|
34
|
-
host.
|
|
34
|
+
host.deviceInvitations
|
|
35
35
|
);
|
|
36
36
|
// prettier-ignore
|
|
37
|
-
const service2:
|
|
37
|
+
const service2: DeviceInvitationsService = new DeviceInvitationsServiceImpl(
|
|
38
38
|
guest.identityManager,
|
|
39
|
-
guest.
|
|
39
|
+
guest.deviceInvitations
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
const success1 = new Trigger<Invitation>();
|
|
@@ -45,11 +45,11 @@ describe('services/halo-invitation-service', () => {
|
|
|
45
45
|
const authenticationCode = new Trigger<string>();
|
|
46
46
|
|
|
47
47
|
{
|
|
48
|
-
const proxy1 = new
|
|
48
|
+
const proxy1 = new DeviceInvitationsProxy(service1);
|
|
49
49
|
const observable1 = proxy1.createInvitation();
|
|
50
50
|
observable1.subscribe({
|
|
51
51
|
onConnecting: (invitation: Invitation) => {
|
|
52
|
-
const proxy2 = new
|
|
52
|
+
const proxy2 = new DeviceInvitationsProxy(service2);
|
|
53
53
|
const observable2 = proxy2.acceptInvitation(invitation);
|
|
54
54
|
observable2.subscribe({
|
|
55
55
|
onAuthenticating: async () => {
|
package/src/packlets/invitations/{halo-invitations-service.ts → device-invitations-service.ts}
RENAMED
|
@@ -11,7 +11,7 @@ import { AbstractInvitationsService } from './invitations-service';
|
|
|
11
11
|
/**
|
|
12
12
|
* Adapts invitation service observable to client/service stream.
|
|
13
13
|
*/
|
|
14
|
-
export class
|
|
14
|
+
export class DeviceInvitationsServiceImpl extends AbstractInvitationsService {
|
|
15
15
|
// prettier-ignore
|
|
16
16
|
constructor (
|
|
17
17
|
identityManager: IdentityManager,
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
export * from './encoder';
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
6
|
+
export * from './device-invitations-handler';
|
|
7
|
+
export * from './device-invitations-proxy';
|
|
8
|
+
export * from './device-invitations-service';
|
|
9
9
|
export * from './invitations';
|
|
10
10
|
export * from './invitations-handler';
|
|
11
11
|
export * from './invitations-proxy';
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { PublicKey } from '@dxos/keys';
|
|
6
6
|
import { NetworkManager } from '@dxos/network-manager';
|
|
7
7
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
8
|
+
import { AuthMethod } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
8
9
|
|
|
9
10
|
import { AuthenticatingInvitationObservable, CancellableInvitationObservable } from './invitations';
|
|
10
11
|
|
|
@@ -13,6 +14,11 @@ export type InvitationsOptions = {
|
|
|
13
14
|
timeout?: number;
|
|
14
15
|
// Used for debugging.
|
|
15
16
|
swarmKey?: PublicKey;
|
|
17
|
+
/**
|
|
18
|
+
* Authentication method.
|
|
19
|
+
* @default AuthMethod.SHARED_SECRET
|
|
20
|
+
*/
|
|
21
|
+
authMethod?: AuthMethod;
|
|
16
22
|
};
|
|
17
23
|
|
|
18
24
|
/**
|
|
@@ -43,8 +43,8 @@ export abstract class AbstractInvitationsService<T = void> implements Invitation
|
|
|
43
43
|
log('stream opened', this.getLoggingContext());
|
|
44
44
|
|
|
45
45
|
let invitationId: string;
|
|
46
|
-
const { type, swarmKey } = invitation;
|
|
47
|
-
const observable = invitationsHandler.createInvitation(context, { type, swarmKey });
|
|
46
|
+
const { type, swarmKey, authMethod } = invitation;
|
|
47
|
+
const observable = invitationsHandler.createInvitation(context, { type, swarmKey, authMethod });
|
|
48
48
|
observable.subscribe({
|
|
49
49
|
onConnecting: (invitation) => {
|
|
50
50
|
assert(invitation.invitationId);
|
|
@@ -7,7 +7,7 @@ import assert from 'node:assert';
|
|
|
7
7
|
|
|
8
8
|
import { asyncChain, latch, Trigger } from '@dxos/async';
|
|
9
9
|
import { raise } from '@dxos/debug';
|
|
10
|
-
import { testLocalDatabase } from '@dxos/echo-
|
|
10
|
+
import { testLocalDatabase } from '@dxos/echo-pipeline/testing';
|
|
11
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
12
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
13
13
|
import { afterTest, describe, test } from '@dxos/test';
|
|
@@ -7,7 +7,7 @@ import assert from 'node:assert';
|
|
|
7
7
|
import { scheduleTask, sleep, Trigger } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { createAdmissionCredentials, generatePasscode, getCredentialAssertion } from '@dxos/credentials';
|
|
10
|
-
import { SigningContext } from '@dxos/echo-
|
|
10
|
+
import { SigningContext } from '@dxos/echo-pipeline';
|
|
11
11
|
import { writeMessages } from '@dxos/feed-store';
|
|
12
12
|
import { Keyring } from '@dxos/keyring';
|
|
13
13
|
import { PublicKey } from '@dxos/keys';
|
|
@@ -20,7 +20,9 @@ import { ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
|
20
20
|
import {
|
|
21
21
|
AuthenticationRequest,
|
|
22
22
|
AuthenticationResponse,
|
|
23
|
+
AuthMethod,
|
|
23
24
|
Introduction,
|
|
25
|
+
IntroductionResponse,
|
|
24
26
|
SpaceAdmissionCredentials,
|
|
25
27
|
SpaceAdmissionRequest,
|
|
26
28
|
SpaceHostService
|
|
@@ -70,7 +72,8 @@ export class SpaceInvitationsHandler extends AbstractInvitationsHandler<DataSpac
|
|
|
70
72
|
invitationId: PublicKey.random().toHex(),
|
|
71
73
|
swarmKey: swarmKey ?? PublicKey.random(),
|
|
72
74
|
spaceKey: space.key,
|
|
73
|
-
|
|
75
|
+
authMethod: options?.authMethod ?? AuthMethod.SHARED_SECRET,
|
|
76
|
+
authenticationCode: generatePasscode(AUTHENTICATION_CODE_LENGTH) // TODO(dmaretskyi): Don't generate if authMethod === NONE .
|
|
74
77
|
};
|
|
75
78
|
|
|
76
79
|
const ctx = new Context({
|
|
@@ -85,7 +88,7 @@ export class SpaceInvitationsHandler extends AbstractInvitationsHandler<DataSpac
|
|
|
85
88
|
await swarmConnection?.close();
|
|
86
89
|
});
|
|
87
90
|
|
|
88
|
-
let
|
|
91
|
+
let authenticationPassed = false;
|
|
89
92
|
let authenticationRetry = 0;
|
|
90
93
|
|
|
91
94
|
// Called for every connecting peer.
|
|
@@ -106,18 +109,41 @@ export class SpaceInvitationsHandler extends AbstractInvitationsHandler<DataSpac
|
|
|
106
109
|
// TODO(burdon): Is this the right place to set this state?
|
|
107
110
|
// TODO(dmaretskyi): Should we expose guest's profile in this callback?
|
|
108
111
|
observable.callback.onAuthenticating?.(invitation);
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
spaceKey:
|
|
115
|
+
type === Invitation.Type.INTERACTIVE_TESTING || type === Invitation.Type.MULTIUSE_TESTING
|
|
116
|
+
? space.key
|
|
117
|
+
: undefined,
|
|
118
|
+
authMethod: invitation.authMethod!
|
|
119
|
+
};
|
|
109
120
|
},
|
|
110
121
|
|
|
111
122
|
authenticate: async ({ authenticationCode: code }) => {
|
|
112
123
|
log('received authentication request', { authenticationCode: code });
|
|
113
124
|
let status = AuthenticationResponse.Status.OK;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
status
|
|
119
|
-
}
|
|
120
|
-
|
|
125
|
+
|
|
126
|
+
switch (invitation.authMethod) {
|
|
127
|
+
case AuthMethod.NONE: {
|
|
128
|
+
log('authentication not required');
|
|
129
|
+
return { status: AuthenticationResponse.Status.OK };
|
|
130
|
+
}
|
|
131
|
+
case AuthMethod.SHARED_SECRET: {
|
|
132
|
+
if (invitation.authenticationCode) {
|
|
133
|
+
if (authenticationRetry++ > MAX_OTP_ATTEMPTS) {
|
|
134
|
+
status = AuthenticationResponse.Status.INVALID_OPT_ATTEMPTS;
|
|
135
|
+
} else if (code !== invitation.authenticationCode) {
|
|
136
|
+
status = AuthenticationResponse.Status.INVALID_OTP;
|
|
137
|
+
} else {
|
|
138
|
+
authenticationPassed = true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
default: {
|
|
144
|
+
log.error('invalid authentication method', { authMethod: invitation.authMethod });
|
|
145
|
+
status = AuthenticationResponse.Status.INTERNAL_ERROR;
|
|
146
|
+
break;
|
|
121
147
|
}
|
|
122
148
|
}
|
|
123
149
|
|
|
@@ -127,13 +153,8 @@ export class SpaceInvitationsHandler extends AbstractInvitationsHandler<DataSpac
|
|
|
127
153
|
requestAdmission: async ({ identityKey, deviceKey, controlFeedKey, dataFeedKey }) => {
|
|
128
154
|
try {
|
|
129
155
|
// Check authenticated.
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
invitation.type !== Invitation.Type.MULTIUSE_TESTING
|
|
133
|
-
) {
|
|
134
|
-
if (invitation.authenticationCode === undefined || invitation.authenticationCode !== authenticationCode) {
|
|
135
|
-
throw new Error(`invalid authentication code: ${authenticationCode}`);
|
|
136
|
-
}
|
|
156
|
+
if (isAuthenticationRequired(invitation) && !authenticationPassed) {
|
|
157
|
+
throw new Error('Not authenticated');
|
|
137
158
|
}
|
|
138
159
|
|
|
139
160
|
log('writing guest credentials', { host: this._signingContext.deviceKey, guest: deviceKey });
|
|
@@ -252,13 +273,22 @@ export class SpaceInvitationsHandler extends AbstractInvitationsHandler<DataSpac
|
|
|
252
273
|
|
|
253
274
|
// 1. Introduce guest to host.
|
|
254
275
|
log('introduce', { guest: this._signingContext.deviceKey });
|
|
255
|
-
await extension.rpc.SpaceHostService.introduce({
|
|
276
|
+
const introductionResponse = await extension.rpc.SpaceHostService.introduce({
|
|
256
277
|
profile: this._signingContext.profile
|
|
257
278
|
});
|
|
279
|
+
log('introduce response', { guest: this._signingContext.deviceKey, response: introductionResponse });
|
|
280
|
+
invitation.authMethod = introductionResponse.authMethod;
|
|
281
|
+
if (introductionResponse.spaceKey) {
|
|
282
|
+
invitation.spaceKey = introductionResponse.spaceKey;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// TODO(dmaretskyi): Add a callback here to notify that we have introduced ourselves to the host (regradless of auth requirements).
|
|
258
286
|
|
|
259
287
|
// 2. Get authentication code.
|
|
260
288
|
// TODO(burdon): Test timeout (options for timeouts at different steps).
|
|
261
|
-
if (invitation
|
|
289
|
+
if (isAuthenticationRequired(invitation)) {
|
|
290
|
+
observable.callback.onAuthenticating?.(invitation);
|
|
291
|
+
|
|
262
292
|
for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
|
|
263
293
|
log('guest waiting for authentication code...');
|
|
264
294
|
observable.callback.onAuthenticating?.(invitation);
|
|
@@ -346,11 +376,16 @@ export class SpaceInvitationsHandler extends AbstractInvitationsHandler<DataSpac
|
|
|
346
376
|
}
|
|
347
377
|
}
|
|
348
378
|
|
|
379
|
+
const isAuthenticationRequired = (invitation: Invitation) =>
|
|
380
|
+
invitation.authMethod !== AuthMethod.NONE &&
|
|
381
|
+
invitation.type !== Invitation.Type.INTERACTIVE_TESTING &&
|
|
382
|
+
invitation.type !== Invitation.Type.MULTIUSE_TESTING;
|
|
383
|
+
|
|
349
384
|
type HostSpaceInvitationExtensionCallbacks = {
|
|
350
385
|
// Deliberately not async to not block the extensions opening.
|
|
351
386
|
onOpen: () => void;
|
|
352
387
|
|
|
353
|
-
introduce: (introduction: Introduction) => Promise<
|
|
388
|
+
introduce: (introduction: Introduction) => Promise<IntroductionResponse>;
|
|
354
389
|
authenticate: (request: AuthenticationRequest) => Promise<AuthenticationResponse>;
|
|
355
390
|
requestAdmission: (request: SpaceAdmissionRequest) => Promise<SpaceAdmissionCredentials>;
|
|
356
391
|
};
|
|
@@ -16,7 +16,7 @@ describe('services/ServiceContext', () => {
|
|
|
16
16
|
const space1 = await device1.dataSpaceManager!.createSpace();
|
|
17
17
|
|
|
18
18
|
const device2 = createServiceContext({ signalContext: networkContext });
|
|
19
|
-
await performInvitation(device1.
|
|
19
|
+
await performInvitation(device1.deviceInvitations, device2.deviceInvitations, undefined);
|
|
20
20
|
|
|
21
21
|
const space2 = await device2.dataSpaceManager!.spaces.get(space1.key);
|
|
22
22
|
await syncItems(space1.dataPipelineController, space2!.dataPipelineController);
|
|
@@ -28,7 +28,7 @@ describe('services/ServiceContext', () => {
|
|
|
28
28
|
await device1.createIdentity();
|
|
29
29
|
|
|
30
30
|
const device2 = createServiceContext({ signalContext: networkContext });
|
|
31
|
-
await performInvitation(device1.
|
|
31
|
+
await performInvitation(device1.deviceInvitations, device2.deviceInvitations, undefined);
|
|
32
32
|
|
|
33
33
|
const space1 = await device1.dataSpaceManager!.createSpace();
|
|
34
34
|
await device2.dataSpaceManager?.updated.waitForCondition(() => !!device2.dataSpaceManager!.spaces.get(space1.key));
|
|
@@ -42,7 +42,7 @@ describe('services/ServiceContext', () => {
|
|
|
42
42
|
await device1.createIdentity();
|
|
43
43
|
|
|
44
44
|
const device2 = createServiceContext({ signalContext: networkContext });
|
|
45
|
-
await performInvitation(device1.
|
|
45
|
+
await performInvitation(device1.deviceInvitations, device2.deviceInvitations, undefined);
|
|
46
46
|
|
|
47
47
|
const identity2 = createServiceContext({ signalContext: networkContext });
|
|
48
48
|
await identity2.createIdentity();
|
|
@@ -7,12 +7,12 @@ import { CredentialConsumer, getCredentialAssertion } from '@dxos/credentials';
|
|
|
7
7
|
import { failUndefined } from '@dxos/debug';
|
|
8
8
|
import {
|
|
9
9
|
valueEncoding,
|
|
10
|
-
DataServiceSubscriptions,
|
|
11
10
|
MetadataStore,
|
|
12
11
|
SpaceManager,
|
|
13
12
|
SigningContext,
|
|
13
|
+
DataServiceSubscriptions,
|
|
14
14
|
SnapshotStore
|
|
15
|
-
} from '@dxos/echo-
|
|
15
|
+
} from '@dxos/echo-pipeline';
|
|
16
16
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
17
17
|
import { Keyring } from '@dxos/keyring';
|
|
18
18
|
import { log } from '@dxos/log';
|
|
@@ -23,7 +23,7 @@ import { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
|
23
23
|
import { Storage } from '@dxos/random-access-storage';
|
|
24
24
|
|
|
25
25
|
import { CreateIdentityOptions, IdentityManager, JoinIdentityParams } from '../identity';
|
|
26
|
-
import {
|
|
26
|
+
import { DeviceInvitationsHandler, SpaceInvitationsHandler } from '../invitations';
|
|
27
27
|
import { DataSpaceManager } from '../spaces/data-space-manager';
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -39,7 +39,7 @@ export class ServiceContext {
|
|
|
39
39
|
public readonly keyring: Keyring;
|
|
40
40
|
public readonly spaceManager: SpaceManager;
|
|
41
41
|
public readonly identityManager: IdentityManager;
|
|
42
|
-
public readonly
|
|
42
|
+
public readonly deviceInvitations: DeviceInvitationsHandler;
|
|
43
43
|
|
|
44
44
|
private _deviceSpaceSync?: CredentialConsumer<any>;
|
|
45
45
|
|
|
@@ -82,7 +82,7 @@ export class ServiceContext {
|
|
|
82
82
|
|
|
83
83
|
// TODO(burdon): _initialize called in multiple places.
|
|
84
84
|
// TODO(burdon): Call _initialize on success.
|
|
85
|
-
this.
|
|
85
|
+
this.deviceInvitations = new DeviceInvitationsHandler({
|
|
86
86
|
networkManager: this.networkManager,
|
|
87
87
|
getIdentity: () => this.identityManager.identity ?? failUndefined(),
|
|
88
88
|
acceptIdentity: this._acceptIdentity.bind(this),
|
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { schema } from '@dxos/protocols';
|
|
6
|
-
import { ProfileService, SystemService, SpaceService } from '@dxos/protocols/proto/dxos/client';
|
|
7
6
|
import {
|
|
8
|
-
|
|
7
|
+
DevicesService,
|
|
8
|
+
DeviceInvitationsService,
|
|
9
|
+
IdentityService,
|
|
10
|
+
NetworkService,
|
|
9
11
|
SpaceInvitationsService,
|
|
10
12
|
SpacesService,
|
|
11
|
-
|
|
12
|
-
NetworkService
|
|
13
|
+
SystemService
|
|
13
14
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
14
15
|
import { DevtoolsHost, TracingService } from '@dxos/protocols/proto/dxos/devtools/host';
|
|
15
16
|
import { DataService } from '@dxos/protocols/proto/dxos/echo/service';
|
|
@@ -20,19 +21,19 @@ import { createServiceBundle, ServiceBundle } from '@dxos/rpc';
|
|
|
20
21
|
//
|
|
21
22
|
|
|
22
23
|
export type ClientServices = {
|
|
23
|
-
|
|
24
|
+
SystemService: SystemService;
|
|
25
|
+
|
|
26
|
+
IdentityService: IdentityService;
|
|
27
|
+
DeviceInvitationsService: DeviceInvitationsService;
|
|
24
28
|
DevicesService: DevicesService;
|
|
25
29
|
|
|
26
30
|
SpaceInvitationsService: SpaceInvitationsService;
|
|
27
31
|
SpacesService: SpacesService;
|
|
32
|
+
DataService: DataService;
|
|
28
33
|
|
|
29
34
|
NetworkService: NetworkService;
|
|
30
35
|
|
|
31
36
|
// TODO(burdon): Deprecated.
|
|
32
|
-
SpaceService: SpaceService;
|
|
33
|
-
DataService: DataService;
|
|
34
|
-
ProfileService: ProfileService;
|
|
35
|
-
SystemService: SystemService;
|
|
36
37
|
DevtoolsHost: DevtoolsHost;
|
|
37
38
|
TracingService: TracingService;
|
|
38
39
|
};
|
|
@@ -52,17 +53,16 @@ export interface ClientServicesProvider {
|
|
|
52
53
|
* Services supported by host.
|
|
53
54
|
*/
|
|
54
55
|
export const clientServiceBundle = createServiceBundle<ClientServices>({
|
|
55
|
-
|
|
56
|
+
SystemService: schema.getService('dxos.client.services.SystemService'),
|
|
57
|
+
IdentityService: schema.getService('dxos.client.services.IdentityService'),
|
|
58
|
+
DeviceInvitationsService: schema.getService('dxos.client.services.DeviceInvitationsService'),
|
|
56
59
|
DevicesService: schema.getService('dxos.client.services.DevicesService'),
|
|
57
60
|
SpaceInvitationsService: schema.getService('dxos.client.services.SpaceInvitationsService'),
|
|
58
61
|
SpacesService: schema.getService('dxos.client.services.SpacesService'),
|
|
62
|
+
DataService: schema.getService('dxos.echo.service.DataService'),
|
|
59
63
|
NetworkService: schema.getService('dxos.client.services.NetworkService'),
|
|
60
64
|
|
|
61
65
|
// TODO(burdon): Deprecated.
|
|
62
|
-
SpaceService: schema.getService('dxos.client.SpaceService'),
|
|
63
|
-
DataService: schema.getService('dxos.echo.service.DataService'),
|
|
64
|
-
ProfileService: schema.getService('dxos.client.ProfileService'),
|
|
65
|
-
SystemService: schema.getService('dxos.client.SystemService'),
|
|
66
66
|
DevtoolsHost: schema.getService('dxos.devtools.host.DevtoolsHost'),
|
|
67
67
|
TracingService: schema.getService('dxos.devtools.host.TracingService')
|
|
68
68
|
});
|
|
@@ -20,8 +20,8 @@ describe('ClientServicesHost', () => {
|
|
|
20
20
|
await host.open();
|
|
21
21
|
afterTest(() => host.close());
|
|
22
22
|
|
|
23
|
-
await host.services.
|
|
24
|
-
const {
|
|
23
|
+
await host.services.IdentityService!.createIdentity({});
|
|
24
|
+
const { spaceKey } = await host.services.SpacesService!.createSpace();
|
|
25
25
|
|
|
26
26
|
const stream = host.services.SpacesService!.queryCredentials({ spaceKey });
|
|
27
27
|
const [done, tick] = latch({ count: 3 });
|
|
@@ -39,18 +39,18 @@ describe('ClientServicesHost', () => {
|
|
|
39
39
|
await host.open();
|
|
40
40
|
afterTest(() => host.close());
|
|
41
41
|
|
|
42
|
-
await host.services.
|
|
42
|
+
await host.services.IdentityService!.createIdentity({});
|
|
43
43
|
|
|
44
44
|
const testCredential = await createMockCredential({
|
|
45
45
|
signer: host._serviceContext.keyring,
|
|
46
46
|
issuer: host._serviceContext.identityManager.identity!.deviceKey
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
// Test if
|
|
49
|
+
// Test if Identity exposes haloSpace key.
|
|
50
50
|
const haloSpace = new Trigger<PublicKey>();
|
|
51
|
-
host.services.
|
|
52
|
-
if (
|
|
53
|
-
haloSpace.wake(
|
|
51
|
+
host.services.IdentityService!.queryIdentity()!.subscribe(({ identity }) => {
|
|
52
|
+
if (identity?.spaceKey) {
|
|
53
|
+
haloSpace.wake(identity.spaceKey);
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -76,7 +76,7 @@ describe('ClientServicesHost', () => {
|
|
|
76
76
|
await host.open();
|
|
77
77
|
afterTest(() => host.close());
|
|
78
78
|
|
|
79
|
-
await host.services.
|
|
79
|
+
await host.services.IdentityService!.createIdentity({});
|
|
80
80
|
|
|
81
81
|
const testCredential = await createMockCredential({
|
|
82
82
|
signer: host._serviceContext.keyring,
|
|
@@ -85,7 +85,7 @@ describe('ClientServicesHost', () => {
|
|
|
85
85
|
|
|
86
86
|
const nonce = new Uint8Array([0, 0, 0, 0]);
|
|
87
87
|
|
|
88
|
-
const presentation = await host.services.
|
|
88
|
+
const presentation = await host.services.IdentityService!.signPresentation({
|
|
89
89
|
presentation: {
|
|
90
90
|
credentials: [testCredential]
|
|
91
91
|
},
|
|
@@ -2,24 +2,29 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
|
|
7
|
+
import { Event } from '@dxos/async';
|
|
5
8
|
import { Config } from '@dxos/config';
|
|
6
9
|
import { raise } from '@dxos/debug';
|
|
7
10
|
import { DocumentModel } from '@dxos/document-model';
|
|
8
|
-
import { DataServiceImpl } from '@dxos/echo-
|
|
11
|
+
import { DataServiceImpl } from '@dxos/echo-pipeline';
|
|
9
12
|
import { log } from '@dxos/log';
|
|
10
13
|
import { ModelFactory } from '@dxos/model-factory';
|
|
11
14
|
import { NetworkManager } from '@dxos/network-manager';
|
|
12
|
-
import {
|
|
15
|
+
import { SystemStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
13
16
|
import { Storage } from '@dxos/random-access-storage';
|
|
14
17
|
import { TextModel } from '@dxos/text-model';
|
|
15
18
|
|
|
16
|
-
import {
|
|
19
|
+
import { TracingServiceImpl } from '../deprecated';
|
|
20
|
+
import { DevicesServiceImpl } from '../devices';
|
|
17
21
|
import { DevtoolsServiceImpl, DevtoolsHostEvents } from '../devtools';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
22
|
+
import { IdentityServiceImpl } from '../identity';
|
|
23
|
+
import { DeviceInvitationsServiceImpl, SpaceInvitationsServiceImpl } from '../invitations';
|
|
20
24
|
import { NetworkServiceImpl } from '../network';
|
|
21
25
|
import { SpacesServiceImpl } from '../spaces';
|
|
22
26
|
import { createStorageObjects } from '../storage';
|
|
27
|
+
import { SystemServiceImpl } from '../system';
|
|
23
28
|
import { VaultResourceLock } from '../vault';
|
|
24
29
|
import { ServiceContext } from './service-context';
|
|
25
30
|
import { ClientServicesProvider, ClientServices, clientServiceBundle } from './service-definitions';
|
|
@@ -48,6 +53,7 @@ export class ClientServicesHost implements ClientServicesProvider {
|
|
|
48
53
|
private readonly _systemService: SystemServiceImpl;
|
|
49
54
|
|
|
50
55
|
private readonly _config: Config;
|
|
56
|
+
private readonly _statusUpdate = new Event<void>();
|
|
51
57
|
private readonly _modelFactory: ModelFactory;
|
|
52
58
|
private readonly _networkManager: NetworkManager;
|
|
53
59
|
private readonly _storage: Storage;
|
|
@@ -64,6 +70,7 @@ export class ClientServicesHost implements ClientServicesProvider {
|
|
|
64
70
|
// TODO(burdon): Create ApolloLink abstraction (see Client).
|
|
65
71
|
networkManager,
|
|
66
72
|
storage = createStorageObjects(config.get('runtime.client.storage', {})!).storage,
|
|
73
|
+
// TODO(wittjosiah): Turn this on by default.
|
|
67
74
|
lockKey
|
|
68
75
|
}: ClientServicesHostParams) {
|
|
69
76
|
this._config = config;
|
|
@@ -82,20 +89,21 @@ export class ClientServicesHost implements ClientServicesProvider {
|
|
|
82
89
|
this._systemService = new SystemServiceImpl({
|
|
83
90
|
config: this._config,
|
|
84
91
|
|
|
85
|
-
|
|
86
|
-
await this._resourceLock?.acquire();
|
|
87
|
-
},
|
|
92
|
+
statusUpdate: this._statusUpdate,
|
|
88
93
|
|
|
89
|
-
|
|
90
|
-
if (!this.isOpen) {
|
|
91
|
-
return { status: Status.INACTIVE };
|
|
92
|
-
}
|
|
94
|
+
getCurrentStatus: () => (this.isOpen ? SystemStatus.ACTIVE : SystemStatus.INACTIVE),
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
onUpdateStatus: async (status: SystemStatus) => {
|
|
97
|
+
if (!this.isOpen && status === SystemStatus.ACTIVE) {
|
|
98
|
+
await this._resourceLock?.acquire();
|
|
99
|
+
} else if (this.isOpen && status === SystemStatus.INACTIVE) {
|
|
100
|
+
await this._resourceLock?.release();
|
|
101
|
+
}
|
|
95
102
|
},
|
|
96
103
|
|
|
97
104
|
onReset: async () => {
|
|
98
|
-
|
|
105
|
+
assert(this._serviceContext, 'service host is closed');
|
|
106
|
+
await this._serviceContext.reset();
|
|
99
107
|
}
|
|
100
108
|
});
|
|
101
109
|
|
|
@@ -123,6 +131,7 @@ export class ClientServicesHost implements ClientServicesProvider {
|
|
|
123
131
|
}
|
|
124
132
|
|
|
125
133
|
log('opening...');
|
|
134
|
+
await this._resourceLock?.acquire();
|
|
126
135
|
|
|
127
136
|
// TODO(wittjosiah): Make re-entrant.
|
|
128
137
|
// TODO(burdon): Break into components.
|
|
@@ -130,34 +139,38 @@ export class ClientServicesHost implements ClientServicesProvider {
|
|
|
130
139
|
|
|
131
140
|
// TODO(burdon): Start to think of DMG (dynamic services).
|
|
132
141
|
this._serviceRegistry.setServices({
|
|
133
|
-
// TODO(burdon): Move to new protobuf definitions.
|
|
134
142
|
SystemService: this._systemService,
|
|
135
143
|
|
|
136
|
-
|
|
137
|
-
this._serviceContext.identityManager,
|
|
138
|
-
this._serviceContext.haloInvitations
|
|
139
|
-
),
|
|
144
|
+
IdentityService: new IdentityServiceImpl(this._serviceContext),
|
|
140
145
|
|
|
141
146
|
DevicesService: new DevicesServiceImpl(this._serviceContext.identityManager),
|
|
142
147
|
|
|
148
|
+
DeviceInvitationsService: new DeviceInvitationsServiceImpl(
|
|
149
|
+
this._serviceContext.identityManager,
|
|
150
|
+
this._serviceContext.deviceInvitations
|
|
151
|
+
),
|
|
152
|
+
|
|
143
153
|
SpaceInvitationsService: new SpaceInvitationsServiceImpl(
|
|
144
154
|
this._serviceContext.identityManager,
|
|
145
155
|
() => this._serviceContext.spaceInvitations ?? raise(new Error('SpaceInvitations not initialized')),
|
|
146
156
|
() => this._serviceContext.dataSpaceManager ?? raise(new Error('SpaceManager not initialized'))
|
|
147
157
|
),
|
|
148
158
|
|
|
149
|
-
SpacesService: new SpacesServiceImpl(
|
|
159
|
+
SpacesService: new SpacesServiceImpl(
|
|
160
|
+
this._serviceContext.identityManager,
|
|
161
|
+
this._serviceContext.spaceManager,
|
|
162
|
+
this._serviceContext.dataServiceSubscriptions,
|
|
163
|
+
async () => {
|
|
164
|
+
await this._serviceContext.initialized.wait();
|
|
165
|
+
return this._serviceContext.dataSpaceManager!;
|
|
166
|
+
}
|
|
167
|
+
),
|
|
150
168
|
|
|
151
169
|
DataService: new DataServiceImpl(this._serviceContext.dataServiceSubscriptions),
|
|
152
170
|
|
|
153
171
|
NetworkService: new NetworkServiceImpl(this._serviceContext.networkManager),
|
|
154
172
|
|
|
155
173
|
// TODO(burdon): Move to new protobuf definitions.
|
|
156
|
-
ProfileService: new ProfileServiceImpl(this._serviceContext),
|
|
157
|
-
|
|
158
|
-
// TODO(burdon): Port old SubscribeSpaces to QueryServices>
|
|
159
|
-
SpaceService: new SpaceServiceImpl(this._serviceContext),
|
|
160
|
-
|
|
161
174
|
TracingService: new TracingServiceImpl(this._config),
|
|
162
175
|
DevtoolsHost: new DevtoolsServiceImpl({
|
|
163
176
|
events: new DevtoolsHostEvents(),
|
|
@@ -168,6 +181,7 @@ export class ClientServicesHost implements ClientServicesProvider {
|
|
|
168
181
|
|
|
169
182
|
await this._serviceContext.open();
|
|
170
183
|
this._open = true;
|
|
184
|
+
this._statusUpdate.emit();
|
|
171
185
|
const deviceKey = this._serviceContext.identityManager.identity?.deviceKey;
|
|
172
186
|
log('opened', { deviceKey });
|
|
173
187
|
}
|
|
@@ -182,6 +196,7 @@ export class ClientServicesHost implements ClientServicesProvider {
|
|
|
182
196
|
this._serviceRegistry.setServices({ SystemService: this._systemService });
|
|
183
197
|
await this._serviceContext.close();
|
|
184
198
|
this._open = false;
|
|
199
|
+
this._statusUpdate.emit();
|
|
185
200
|
log('closed', { deviceKey });
|
|
186
201
|
}
|
|
187
202
|
}
|
|
@@ -6,7 +6,7 @@ import { expect } from 'chai';
|
|
|
6
6
|
|
|
7
7
|
import { createAdmissionCredentials } from '@dxos/credentials';
|
|
8
8
|
import { DocumentModel } from '@dxos/document-model';
|
|
9
|
-
import { AuthStatus, DataServiceSubscriptions } from '@dxos/echo-
|
|
9
|
+
import { AuthStatus, DataServiceSubscriptions } from '@dxos/echo-pipeline';
|
|
10
10
|
import { writeMessages } from '@dxos/feed-store';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { ModelFactory } from '@dxos/model-factory';
|
|
@@ -8,15 +8,15 @@ import { Event, synchronized, trackLeaks } from '@dxos/async';
|
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { getCredentialAssertion } from '@dxos/credentials';
|
|
10
10
|
import {
|
|
11
|
-
DataServiceSubscriptions,
|
|
12
11
|
MetadataStore,
|
|
13
12
|
SigningContext,
|
|
14
|
-
SnapshotStore,
|
|
15
13
|
Space,
|
|
16
14
|
spaceGenesis,
|
|
17
15
|
SpaceManager,
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
DataServiceSubscriptions,
|
|
17
|
+
SnapshotManager,
|
|
18
|
+
SnapshotStore
|
|
19
|
+
} from '@dxos/echo-pipeline';
|
|
20
20
|
import { FeedStore } from '@dxos/feed-store';
|
|
21
21
|
import { Keyring } from '@dxos/keyring';
|
|
22
22
|
import { PublicKey } from '@dxos/keys';
|