@dxos/client-services 0.4.6-main.9c97a50 → 0.4.6-main.b69a2b5
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-7JCJI2VR.mjs → chunk-KFMLOQZY.mjs} +164 -115
- package/dist/lib/browser/chunk-KFMLOQZY.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/testing/index.mjs +7 -7
- package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-YJ2ASSPD.cjs → chunk-QDJO4DXB.cjs} +177 -128
- package/dist/lib/node/chunk-QDJO4DXB.cjs.map +7 -0
- package/dist/lib/node/index.cjs +37 -37
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/packlets/testing/index.cjs +14 -14
- package/dist/lib/node/packlets/testing/index.cjs.map +3 -3
- package/dist/types/src/packlets/identity/identity-manager.d.ts +5 -2
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +0 -1
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +2 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +2 -2
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +2 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +2 -2
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +4 -2
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/package.json +35 -35
- package/src/packlets/identity/identity-manager.test.ts +1 -0
- package/src/packlets/identity/identity-manager.ts +50 -12
- package/src/packlets/identity/identity-service.ts +1 -1
- package/src/packlets/identity/identity.test.ts +9 -9
- package/src/packlets/identity/identity.ts +0 -9
- package/src/packlets/invitations/device-invitation-protocol.ts +5 -2
- package/src/packlets/invitations/invitation-protocol.ts +2 -2
- package/src/packlets/invitations/invitations-handler.ts +11 -2
- package/src/packlets/invitations/invitations-service.ts +8 -2
- package/src/packlets/services/service-host.ts +3 -3
- package/src/packlets/spaces/data-space-manager.ts +3 -3
- package/src/packlets/spaces/data-space.ts +4 -4
- package/src/packlets/testing/invitation-utils.ts +8 -4
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-7JCJI2VR.mjs.map +0 -7
- package/dist/lib/node/chunk-YJ2ASSPD.cjs.map +0 -7
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
//
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
|
-
|
|
5
4
|
import platform from 'platform';
|
|
6
5
|
|
|
7
6
|
import { Event } from '@dxos/async';
|
|
@@ -20,11 +19,12 @@ import { type IdentityRecord, type SpaceMetadata } from '@dxos/protocols/proto/d
|
|
|
20
19
|
import {
|
|
21
20
|
AdmittedFeed,
|
|
22
21
|
type DeviceProfileDocument,
|
|
22
|
+
DeviceType,
|
|
23
23
|
type ProfileDocument,
|
|
24
24
|
} from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
25
25
|
import { Timeframe } from '@dxos/timeframe';
|
|
26
26
|
import { trace as Trace } from '@dxos/tracing';
|
|
27
|
-
import { deferFunction } from '@dxos/util';
|
|
27
|
+
import { isNode, deferFunction } from '@dxos/util';
|
|
28
28
|
|
|
29
29
|
import { createAuthProvider } from './authenticator';
|
|
30
30
|
import { Identity } from './identity';
|
|
@@ -48,10 +48,14 @@ export type JoinIdentityParams = {
|
|
|
48
48
|
* We will try to catch up to this timeframe before starting the data pipeline.
|
|
49
49
|
*/
|
|
50
50
|
controlTimeframe?: Timeframe;
|
|
51
|
+
// Custom device profile, merged with defaults, to be applied once the identity is accepted.
|
|
52
|
+
deviceProfile?: DeviceProfileDocument;
|
|
51
53
|
};
|
|
52
54
|
|
|
53
55
|
export type CreateIdentityOptions = {
|
|
54
56
|
displayName?: string;
|
|
57
|
+
// device profile for device creating the identity.
|
|
58
|
+
deviceProfile?: DeviceProfileDocument;
|
|
55
59
|
};
|
|
56
60
|
|
|
57
61
|
// TODO(dmaretskyi): Rename: represents the peer's state machine.
|
|
@@ -89,6 +93,7 @@ export class IdentityManager {
|
|
|
89
93
|
identityKey: identityRecord.identityKey,
|
|
90
94
|
displayName: this._identity.profileDocument?.displayName,
|
|
91
95
|
});
|
|
96
|
+
|
|
92
97
|
this.stateUpdate.emit();
|
|
93
98
|
}
|
|
94
99
|
log.trace('dxos.halo.identity-manager.open', trace.end({ id: traceId }));
|
|
@@ -98,7 +103,8 @@ export class IdentityManager {
|
|
|
98
103
|
await this._identity?.close(new Context());
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
async createIdentity({ displayName }: CreateIdentityOptions = {}) {
|
|
106
|
+
async createIdentity({ displayName, deviceProfile }: CreateIdentityOptions = {}) {
|
|
107
|
+
// TODO(nf): populate using context from ServiceContext?
|
|
102
108
|
invariant(!this._identity, 'Identity already exists.');
|
|
103
109
|
log('creating identity...');
|
|
104
110
|
|
|
@@ -144,11 +150,8 @@ export class IdentityManager {
|
|
|
144
150
|
// Write device metadata to profile.
|
|
145
151
|
credentials.push(
|
|
146
152
|
await generator.createDeviceProfile({
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
architecture: typeof platform.os?.architecture === 'number' ? String(platform.os.architecture) : undefined,
|
|
150
|
-
os: platform.os?.family,
|
|
151
|
-
osVersion: platform.os?.version,
|
|
153
|
+
...this.createDefaultDeviceProfile(),
|
|
154
|
+
...deviceProfile,
|
|
152
155
|
}),
|
|
153
156
|
);
|
|
154
157
|
for (const credential of credentials) {
|
|
@@ -171,12 +174,42 @@ export class IdentityManager {
|
|
|
171
174
|
});
|
|
172
175
|
this.stateUpdate.emit();
|
|
173
176
|
|
|
174
|
-
log('created identity', {
|
|
177
|
+
log('created identity', {
|
|
178
|
+
identityKey: identity.identityKey,
|
|
179
|
+
deviceKey: identity.deviceKey,
|
|
180
|
+
profile: identity.profileDocument,
|
|
181
|
+
});
|
|
175
182
|
return identity;
|
|
176
183
|
}
|
|
177
184
|
|
|
185
|
+
// TODO(nf): receive platform info rather than generating it here.
|
|
186
|
+
createDefaultDeviceProfile(): DeviceProfileDocument {
|
|
187
|
+
let type: DeviceType;
|
|
188
|
+
// TODO(nf): call Platform service instead?
|
|
189
|
+
if (isNode()) {
|
|
190
|
+
type = DeviceType.AGENT;
|
|
191
|
+
} else {
|
|
192
|
+
if (platform.name?.startsWith('iOS') || platform.name?.startsWith('Android')) {
|
|
193
|
+
type = DeviceType.MOBILE;
|
|
194
|
+
} else if ((globalThis as any).__args) {
|
|
195
|
+
type = DeviceType.NATIVE;
|
|
196
|
+
} else {
|
|
197
|
+
type = DeviceType.BROWSER;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
type,
|
|
203
|
+
platform: platform.name,
|
|
204
|
+
platformVersion: platform.version,
|
|
205
|
+
architecture: typeof platform.os?.architecture === 'number' ? String(platform.os.architecture) : undefined,
|
|
206
|
+
os: platform.os?.family,
|
|
207
|
+
osVersion: platform.os?.version,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
178
211
|
/**
|
|
179
|
-
* Accept an existing identity. Expects
|
|
212
|
+
* Accept an existing identity. Expects its device key to be authorized (now or later).
|
|
180
213
|
*/
|
|
181
214
|
async acceptIdentity(params: JoinIdentityParams) {
|
|
182
215
|
log('accepting identity', { params });
|
|
@@ -204,6 +237,10 @@ export class IdentityManager {
|
|
|
204
237
|
displayName: this._identity.profileDocument?.displayName,
|
|
205
238
|
});
|
|
206
239
|
|
|
240
|
+
await this.updateDeviceProfile({
|
|
241
|
+
...this.createDefaultDeviceProfile(),
|
|
242
|
+
...params.deviceProfile,
|
|
243
|
+
});
|
|
207
244
|
this.stateUpdate.emit();
|
|
208
245
|
log('accepted identity', { identityKey: identity.identityKey, deviceKey: identity.deviceKey });
|
|
209
246
|
return identity;
|
|
@@ -236,7 +273,7 @@ export class IdentityManager {
|
|
|
236
273
|
// const generator = new CredentialGenerator(this._keyring, this._identity.identityKey, this._identity.deviceKey);
|
|
237
274
|
// const credential = await generator.createDeviceProfile(profile);
|
|
238
275
|
|
|
239
|
-
const credential = await this._identity.
|
|
276
|
+
const credential = await this._identity.getDeviceCredentialSigner().createCredential({
|
|
240
277
|
subject: this._identity.deviceKey,
|
|
241
278
|
assertion: {
|
|
242
279
|
'@type': 'dxos.halo.credentials.DeviceProfile',
|
|
@@ -274,7 +311,7 @@ export class IdentityManager {
|
|
|
274
311
|
},
|
|
275
312
|
identityKey: identityRecord.identityKey,
|
|
276
313
|
});
|
|
277
|
-
space.setControlFeed(controlFeed);
|
|
314
|
+
await space.setControlFeed(controlFeed);
|
|
278
315
|
space.setDataFeed(dataFeed);
|
|
279
316
|
|
|
280
317
|
const identity: Identity = new Identity({
|
|
@@ -290,6 +327,7 @@ export class IdentityManager {
|
|
|
290
327
|
identity.controlPipeline.state.setTargetTimeframe(identityRecord.haloSpace.controlTimeframe);
|
|
291
328
|
}
|
|
292
329
|
|
|
330
|
+
identity.stateUpdate.on(() => this.stateUpdate.emit());
|
|
293
331
|
return identity;
|
|
294
332
|
}
|
|
295
333
|
|
|
@@ -28,7 +28,7 @@ export class IdentityServiceImpl implements IdentityService {
|
|
|
28
28
|
) {}
|
|
29
29
|
|
|
30
30
|
async createIdentity(request: CreateIdentityRequest): Promise<Identity> {
|
|
31
|
-
await this._createIdentity(request.profile
|
|
31
|
+
await this._createIdentity({ displayName: request.profile?.displayName, deviceProfile: request.deviceProfile });
|
|
32
32
|
return this._getIdentity()!;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -96,9 +96,9 @@ describe('identity/identity', () => {
|
|
|
96
96
|
metadataStore,
|
|
97
97
|
snapshotManager: new SnapshotManager(snapshotStore, blobStore, protocol.blobSync),
|
|
98
98
|
snapshotId: undefined,
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
});
|
|
100
|
+
await space.setControlFeed(controlFeed);
|
|
101
|
+
await space.setDataFeed(dataFeed);
|
|
102
102
|
|
|
103
103
|
const identity = new Identity({
|
|
104
104
|
signer: keyring,
|
|
@@ -209,9 +209,9 @@ describe('identity/identity', () => {
|
|
|
209
209
|
modelFactory: createDefaultModelFactory(),
|
|
210
210
|
metadataStore,
|
|
211
211
|
snapshotManager: new SnapshotManager(snapshotStore, blobStore, protocol.blobSync),
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
});
|
|
213
|
+
await space.setControlFeed(controlFeed);
|
|
214
|
+
await space.setDataFeed(dataFeed);
|
|
215
215
|
|
|
216
216
|
const identity = (identity1 = new Identity({
|
|
217
217
|
signer: keyring,
|
|
@@ -300,9 +300,9 @@ describe('identity/identity', () => {
|
|
|
300
300
|
modelFactory: createDefaultModelFactory(),
|
|
301
301
|
metadataStore,
|
|
302
302
|
snapshotManager: new SnapshotManager(snapshotStore, blobStore, protocol.blobSync),
|
|
303
|
-
})
|
|
304
|
-
|
|
305
|
-
|
|
303
|
+
});
|
|
304
|
+
await space.setControlFeed(controlFeed);
|
|
305
|
+
await space.setDataFeed(dataFeed);
|
|
306
306
|
|
|
307
307
|
const identity = (identity2 = new Identity({
|
|
308
308
|
signer: keyring,
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
ProfileStateMachine,
|
|
14
14
|
} from '@dxos/credentials';
|
|
15
15
|
import { type Signer } from '@dxos/crypto';
|
|
16
|
-
import { failUndefined } from '@dxos/debug';
|
|
17
16
|
import { type Space } from '@dxos/echo-pipeline';
|
|
18
17
|
import { writeMessages } from '@dxos/feed-store';
|
|
19
18
|
import { invariant } from '@dxos/invariant';
|
|
@@ -129,14 +128,6 @@ export class Identity {
|
|
|
129
128
|
return this._deviceStateMachine.deviceCredentialChain;
|
|
130
129
|
}
|
|
131
130
|
|
|
132
|
-
getAdmissionCredentials(): DeviceAdmissionRequest {
|
|
133
|
-
return {
|
|
134
|
-
deviceKey: this.deviceKey,
|
|
135
|
-
controlFeedKey: this.space.controlFeedKey ?? failUndefined(),
|
|
136
|
-
dataFeedKey: this.space.dataFeedKey ?? failUndefined(),
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
131
|
/**
|
|
141
132
|
* Issues credentials as identity.
|
|
142
133
|
* Requires identity to be ready.
|
|
@@ -6,6 +6,7 @@ import { invariant } from '@dxos/invariant';
|
|
|
6
6
|
import { type Keyring } from '@dxos/keyring';
|
|
7
7
|
import { AlreadyJoinedError } from '@dxos/protocols';
|
|
8
8
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
|
+
import type { DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
9
10
|
import {
|
|
10
11
|
type AdmissionRequest,
|
|
11
12
|
type AdmissionResponse,
|
|
@@ -62,7 +63,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
|
|
|
62
63
|
return {};
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
async createAdmissionRequest(): Promise<AdmissionRequest> {
|
|
66
|
+
async createAdmissionRequest(deviceProfile?: DeviceProfileDocument): Promise<AdmissionRequest> {
|
|
66
67
|
const deviceKey = await this._keyring.createKey();
|
|
67
68
|
const controlFeedKey = await this._keyring.createKey();
|
|
68
69
|
const dataFeedKey = await this._keyring.createKey();
|
|
@@ -72,6 +73,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
|
|
|
72
73
|
deviceKey,
|
|
73
74
|
controlFeedKey,
|
|
74
75
|
dataFeedKey,
|
|
76
|
+
profile: deviceProfile,
|
|
75
77
|
},
|
|
76
78
|
};
|
|
77
79
|
}
|
|
@@ -81,7 +83,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
|
|
|
81
83
|
const { identityKey, haloSpaceKey, genesisFeedKey, controlTimeframe } = response.device;
|
|
82
84
|
|
|
83
85
|
invariant(request.device);
|
|
84
|
-
const { deviceKey, controlFeedKey, dataFeedKey } = request.device;
|
|
86
|
+
const { deviceKey, controlFeedKey, dataFeedKey, profile } = request.device;
|
|
85
87
|
|
|
86
88
|
// TODO(wittjosiah): When multiple identities are supported, verify identity doesn't already exist before accepting.
|
|
87
89
|
|
|
@@ -93,6 +95,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
|
|
|
93
95
|
controlFeedKey,
|
|
94
96
|
dataFeedKey,
|
|
95
97
|
controlTimeframe,
|
|
98
|
+
deviceProfile: profile,
|
|
96
99
|
});
|
|
97
100
|
|
|
98
101
|
return { identityKey };
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import type { ApiError } from '@dxos/protocols';
|
|
6
6
|
import type { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
7
|
-
import type { ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
7
|
+
import type { ProfileDocument, DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
8
8
|
import type {
|
|
9
9
|
AdmissionRequest,
|
|
10
10
|
AdmissionResponse,
|
|
@@ -54,7 +54,7 @@ export interface InvitationProtocol {
|
|
|
54
54
|
/**
|
|
55
55
|
* Get key information to send to the host in order to create an admission credential for the guest.
|
|
56
56
|
*/
|
|
57
|
-
createAdmissionRequest(): Promise<AdmissionRequest>;
|
|
57
|
+
createAdmissionRequest(deviceProfile?: DeviceProfileDocument): Promise<AdmissionRequest>;
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* Redeem the admission credential.
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from '@dxos/network-manager';
|
|
23
23
|
import { InvalidInvitationExtensionRoleError, trace } from '@dxos/protocols';
|
|
24
24
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
25
|
+
import { type DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
25
26
|
import { AuthenticationResponse } from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
26
27
|
|
|
27
28
|
import {
|
|
@@ -210,10 +211,18 @@ export class InvitationsHandler {
|
|
|
210
211
|
return observable;
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
acceptInvitation(
|
|
214
|
+
acceptInvitation(
|
|
215
|
+
protocol: InvitationProtocol,
|
|
216
|
+
invitation: Invitation,
|
|
217
|
+
deviceProfile?: DeviceProfileDocument,
|
|
218
|
+
): AuthenticatingInvitation {
|
|
214
219
|
const { timeout = INVITATION_TIMEOUT } = invitation;
|
|
215
220
|
invariant(protocol);
|
|
216
221
|
|
|
222
|
+
// TODO(nf): duplicate check in InvitationsService
|
|
223
|
+
if (deviceProfile) {
|
|
224
|
+
invariant(invitation.kind === Invitation.Kind.DEVICE, 'deviceProfile provided for non-device invitation');
|
|
225
|
+
}
|
|
217
226
|
const authenticated = new Trigger<string>();
|
|
218
227
|
|
|
219
228
|
// TODO(dmaretskyi): Turn into state?
|
|
@@ -307,7 +316,7 @@ export class InvitationsHandler {
|
|
|
307
316
|
|
|
308
317
|
// 3. Send admission credentials to host (with local space keys).
|
|
309
318
|
log('request admission', { ...protocol.toJSON() });
|
|
310
|
-
const admissionRequest = await protocol.createAdmissionRequest();
|
|
319
|
+
const admissionRequest = await protocol.createAdmissionRequest(deviceProfile);
|
|
311
320
|
const admissionResponse = await extension.rpc.InvitationHostService.admit(admissionRequest);
|
|
312
321
|
|
|
313
322
|
// Remote connection no longer needed.
|
|
@@ -9,6 +9,7 @@ import { invariant } from '@dxos/invariant';
|
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import {
|
|
11
11
|
type AuthenticationRequest,
|
|
12
|
+
type AcceptInvitationRequest,
|
|
12
13
|
Invitation,
|
|
13
14
|
type InvitationsService,
|
|
14
15
|
QueryInvitationsResponse,
|
|
@@ -72,15 +73,20 @@ export class InvitationsServiceImpl implements InvitationsService {
|
|
|
72
73
|
});
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
acceptInvitation(options:
|
|
76
|
+
acceptInvitation({ invitation: options, deviceProfile }: AcceptInvitationRequest): Stream<Invitation> {
|
|
76
77
|
let invitation: AuthenticatingInvitation;
|
|
77
78
|
|
|
79
|
+
// TODO(nf): duplicate check in InvitationHandler
|
|
80
|
+
if (deviceProfile) {
|
|
81
|
+
invariant(options.kind === Invitation.Kind.DEVICE, 'deviceProfile provided for non-device invitation');
|
|
82
|
+
}
|
|
83
|
+
|
|
78
84
|
const existingInvitation = this._acceptInvitations.get(options.invitationId);
|
|
79
85
|
if (existingInvitation) {
|
|
80
86
|
invitation = existingInvitation;
|
|
81
87
|
} else {
|
|
82
88
|
const handler = this._getHandler(options);
|
|
83
|
-
invitation = this._invitationsHandler.acceptInvitation(handler, options);
|
|
89
|
+
invitation = this._invitationsHandler.acceptInvitation(handler, options, deviceProfile);
|
|
84
90
|
this._acceptInvitations.set(invitation.get().invitationId, invitation);
|
|
85
91
|
this._invitationAccepted.emit(invitation.get());
|
|
86
92
|
}
|
|
@@ -8,7 +8,7 @@ import { type Config } from '@dxos/config';
|
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { DocumentModel } from '@dxos/document-model';
|
|
10
10
|
import { DataServiceImpl } from '@dxos/echo-pipeline';
|
|
11
|
-
import { type TypedObject, base, getRawDoc, type
|
|
11
|
+
import { type TypedObject, base, getRawDoc, type SpaceDoc } from '@dxos/echo-schema';
|
|
12
12
|
import { invariant } from '@dxos/invariant';
|
|
13
13
|
import { PublicKey } from '@dxos/keys';
|
|
14
14
|
import { log } from '@dxos/log';
|
|
@@ -348,10 +348,10 @@ export class ClientServicesHost {
|
|
|
348
348
|
|
|
349
349
|
const automergeIndex = space.automergeSpaceState.rootUrl;
|
|
350
350
|
invariant(automergeIndex);
|
|
351
|
-
const document = await this._serviceContext.automergeHost.repo.find<
|
|
351
|
+
const document = await this._serviceContext.automergeHost.repo.find<SpaceDoc>(automergeIndex as any);
|
|
352
352
|
await document.whenReady();
|
|
353
353
|
|
|
354
|
-
document.change((doc:
|
|
354
|
+
document.change((doc: SpaceDoc) => {
|
|
355
355
|
assignDeep(doc, ['objects', obj[base]._id], getRawDoc(obj).handle.docSync());
|
|
356
356
|
});
|
|
357
357
|
|
|
@@ -143,7 +143,7 @@ export class DataSpaceManager {
|
|
|
143
143
|
|
|
144
144
|
const automergeRoot = this._automergeHost.repo.create();
|
|
145
145
|
automergeRoot.change((doc: any) => {
|
|
146
|
-
doc.
|
|
146
|
+
doc.access = { spaceKey: spaceKey.toHex() };
|
|
147
147
|
});
|
|
148
148
|
|
|
149
149
|
const space = await this._constructSpace(metadata);
|
|
@@ -240,8 +240,8 @@ export class DataSpaceManager {
|
|
|
240
240
|
},
|
|
241
241
|
memberKey: this._signingContext.identityKey,
|
|
242
242
|
});
|
|
243
|
-
controlFeed && space.setControlFeed(controlFeed);
|
|
244
|
-
dataFeed && space.setDataFeed(dataFeed);
|
|
243
|
+
controlFeed && (await space.setControlFeed(controlFeed));
|
|
244
|
+
dataFeed && (await space.setDataFeed(dataFeed));
|
|
245
245
|
|
|
246
246
|
const dataSpace = new DataSpace({
|
|
247
247
|
inner: space,
|
|
@@ -331,7 +331,7 @@ export class DataSpace {
|
|
|
331
331
|
const credentials: Credential[] = [];
|
|
332
332
|
if (!this.inner.controlFeedKey) {
|
|
333
333
|
const controlFeed = await this._feedStore.openFeed(await this._keyring.createKey(), { writable: true });
|
|
334
|
-
this.inner.setControlFeed(controlFeed);
|
|
334
|
+
await this.inner.setControlFeed(controlFeed);
|
|
335
335
|
|
|
336
336
|
credentials.push(
|
|
337
337
|
await this._signingContext.credentialSigner.createCredential({
|
|
@@ -351,7 +351,7 @@ export class DataSpace {
|
|
|
351
351
|
writable: true,
|
|
352
352
|
sparse: true,
|
|
353
353
|
});
|
|
354
|
-
this.inner.setDataFeed(dataFeed);
|
|
354
|
+
await this.inner.setDataFeed(dataFeed);
|
|
355
355
|
|
|
356
356
|
credentials.push(
|
|
357
357
|
await this._signingContext.credentialSigner.createCredential({
|
|
@@ -391,9 +391,9 @@ export class DataSpace {
|
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
const doc = handle.docSync() ?? failedInvariant();
|
|
394
|
-
if (!doc.
|
|
394
|
+
if (!doc.access?.spaceKey) {
|
|
395
395
|
handle.change((doc: any) => {
|
|
396
|
-
doc.
|
|
396
|
+
doc.access = { spaceKey: this.key.toHex() };
|
|
397
397
|
});
|
|
398
398
|
}
|
|
399
399
|
} catch (err) {
|
|
@@ -6,6 +6,7 @@ import { Trigger } from '@dxos/async';
|
|
|
6
6
|
import { InvitationEncoder, type AuthenticatingInvitation, type CancellableInvitation } from '@dxos/client-protocol';
|
|
7
7
|
import { invariant } from '@dxos/invariant';
|
|
8
8
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
|
+
import { type DeviceProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
9
10
|
|
|
10
11
|
import { ServiceContext } from '../services';
|
|
11
12
|
|
|
@@ -21,7 +22,7 @@ export type InvitationHost = {
|
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
export type InvitationGuest = {
|
|
24
|
-
join(invitation: Invitation | string): AuthenticatingInvitation;
|
|
25
|
+
join(invitation: Invitation | string, deviceProfile?: DeviceProfileDocument): AuthenticatingInvitation;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
export type PerformInvitationCallbacks<T> = {
|
|
@@ -43,6 +44,7 @@ export type PerformInvitationParams = {
|
|
|
43
44
|
host?: PerformInvitationCallbacks<CancellableInvitation>;
|
|
44
45
|
guest?: PerformInvitationCallbacks<AuthenticatingInvitation>;
|
|
45
46
|
};
|
|
47
|
+
guestDeviceProfile?: DeviceProfileDocument;
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
export type Result = { invitation?: Invitation; error?: Error };
|
|
@@ -52,6 +54,7 @@ export const performInvitation = ({
|
|
|
52
54
|
guest,
|
|
53
55
|
options,
|
|
54
56
|
hooks,
|
|
57
|
+
guestDeviceProfile,
|
|
55
58
|
}: PerformInvitationParams): [Promise<Result>, Promise<Result>] => {
|
|
56
59
|
const hostComplete = new Trigger<Result>();
|
|
57
60
|
const guestComplete = new Trigger<Result>();
|
|
@@ -65,7 +68,7 @@ export const performInvitation = ({
|
|
|
65
68
|
if (hooks?.host?.onConnecting?.(hostObservable)) {
|
|
66
69
|
break;
|
|
67
70
|
}
|
|
68
|
-
const guestObservable = acceptInvitation(guest, hostInvitation);
|
|
71
|
+
const guestObservable = acceptInvitation(guest, hostInvitation, guestDeviceProfile);
|
|
69
72
|
guestObservable.subscribe(
|
|
70
73
|
async (guestInvitation: Invitation) => {
|
|
71
74
|
switch (guestInvitation.state) {
|
|
@@ -205,13 +208,14 @@ const createInvitation = (
|
|
|
205
208
|
const acceptInvitation = (
|
|
206
209
|
guest: ServiceContext | InvitationGuest,
|
|
207
210
|
invitation: Invitation,
|
|
211
|
+
guestDeviceProfile?: DeviceProfileDocument,
|
|
208
212
|
): AuthenticatingInvitation => {
|
|
209
213
|
invitation = sanitizeInvitation(invitation);
|
|
210
214
|
|
|
211
215
|
if (guest instanceof ServiceContext) {
|
|
212
216
|
const guestHandler = guest.getInvitationHandler({ kind: invitation.kind });
|
|
213
|
-
return guest.invitations.acceptInvitation(guestHandler, invitation);
|
|
217
|
+
return guest.invitations.acceptInvitation(guestHandler, invitation, guestDeviceProfile);
|
|
214
218
|
}
|
|
215
219
|
|
|
216
|
-
return guest.join(invitation);
|
|
220
|
+
return guest.join(invitation, guestDeviceProfile);
|
|
217
221
|
};
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const DXOS_VERSION = "0.4.6-main.
|
|
1
|
+
export const DXOS_VERSION = "0.4.6-main.b69a2b5";
|