@dxos/client-services 0.10.0 → 0.11.0
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/chunk-client-services-layer.mjs +11425 -0
- package/dist/lib/chunk-client-services-layer.mjs.map +1 -0
- package/dist/lib/chunk-decorate.mjs +9 -0
- package/dist/lib/index.mjs +731 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/packlets/diagnostics/browser-diagnostics-broadcast.mjs +72 -0
- package/dist/lib/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +1 -0
- package/dist/lib/packlets/diagnostics/diagnostics-broadcast.mjs +14 -0
- package/dist/lib/packlets/diagnostics/diagnostics-broadcast.mjs.map +1 -0
- package/dist/lib/packlets/locks/browser.mjs +105 -0
- package/dist/lib/packlets/locks/browser.mjs.map +1 -0
- package/dist/lib/packlets/locks/node.mjs +53 -0
- package/dist/lib/packlets/locks/node.mjs.map +1 -0
- package/dist/lib/testing.mjs +570 -0
- package/dist/lib/testing.mjs.map +1 -0
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts +21 -4
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +8 -7
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts +7 -5
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts +30 -29
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts +2 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +2 -2
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-collector.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +1 -8
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- 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/contacts-service.d.ts +9 -6
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +32 -3
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +23 -4
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +15 -20
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- 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/invitations/edge-invitation-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +17 -0
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts +25 -4
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +11 -11
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts +14 -12
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/metadata/index.d.ts +3 -0
- package/dist/types/src/packlets/metadata/index.d.ts.map +1 -0
- package/dist/types/src/packlets/metadata/metadata-store.d.ts +107 -0
- package/dist/types/src/packlets/metadata/metadata-store.d.ts.map +1 -0
- package/dist/types/src/packlets/metadata/metadata-store.test.d.ts +2 -0
- package/dist/types/src/packlets/metadata/metadata-store.test.d.ts.map +1 -0
- package/dist/types/src/packlets/metadata/sqlite-metadata-store.d.ts +65 -0
- package/dist/types/src/packlets/metadata/sqlite-metadata-store.d.ts.map +1 -0
- package/dist/types/src/packlets/network/network-service.d.ts +15 -14
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/pipeline/codec.d.ts +11 -0
- package/dist/types/src/packlets/pipeline/codec.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/feeds.d.ts +7 -0
- package/dist/types/src/packlets/pipeline/feeds.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/index.d.ts +5 -0
- package/dist/types/src/packlets/pipeline/index.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/message-selector.d.ts +11 -0
- package/dist/types/src/packlets/pipeline/message-selector.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/pipeline-stress.test.d.ts +2 -0
- package/dist/types/src/packlets/pipeline/pipeline-stress.test.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/pipeline.d.ts +131 -0
- package/dist/types/src/packlets/pipeline/pipeline.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/pipeline.test.d.ts +2 -0
- package/dist/types/src/packlets/pipeline/pipeline.test.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/testing/index.d.ts +2 -0
- package/dist/types/src/packlets/pipeline/testing/index.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/testing/test-feed-builder.d.ts +9 -0
- package/dist/types/src/packlets/pipeline/testing/test-feed-builder.d.ts.map +1 -0
- package/dist/types/src/packlets/pipeline/timeframe-clock.d.ts +31 -0
- package/dist/types/src/packlets/pipeline/timeframe-clock.d.ts.map +1 -0
- package/dist/types/src/packlets/services/client-services-layer.d.ts +21 -0
- package/dist/types/src/packlets/services/client-services-layer.d.ts.map +1 -0
- package/dist/types/src/packlets/services/cross-device-space-synchronizer.d.ts +28 -0
- package/dist/types/src/packlets/services/cross-device-space-synchronizer.d.ts.map +1 -0
- package/dist/types/src/packlets/services/effect-rpc.test.d.ts +2 -0
- package/dist/types/src/packlets/services/effect-rpc.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/feed-syncer.d.ts +22 -2
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -1
- package/dist/types/src/packlets/services/index.d.ts +2 -2
- package/dist/types/src/packlets/services/index.d.ts.map +1 -1
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +38 -57
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +82 -31
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/sqlite-storage.d.ts +29 -0
- package/dist/types/src/packlets/services/sqlite-storage.d.ts.map +1 -1
- package/dist/types/src/packlets/services/sqlite-storage.test.d.ts +2 -0
- package/dist/types/src/packlets/services/sqlite-storage.test.d.ts.map +1 -0
- package/dist/types/src/packlets/space/admission-discovery-extension.d.ts +30 -0
- package/dist/types/src/packlets/space/admission-discovery-extension.d.ts.map +1 -0
- package/dist/types/src/packlets/space/auth.d.ts +24 -0
- package/dist/types/src/packlets/space/auth.d.ts.map +1 -0
- package/dist/types/src/packlets/space/control-pipeline.d.ts +46 -0
- package/dist/types/src/packlets/space/control-pipeline.d.ts.map +1 -0
- package/dist/types/src/packlets/space/control-pipeline.test.d.ts +2 -0
- package/dist/types/src/packlets/space/control-pipeline.test.d.ts.map +1 -0
- package/dist/types/src/packlets/space/index.d.ts +6 -0
- package/dist/types/src/packlets/space/index.d.ts.map +1 -0
- package/dist/types/src/packlets/space/replication.browser.test.d.ts +2 -0
- package/dist/types/src/packlets/space/replication.browser.test.d.ts.map +1 -0
- package/dist/types/src/packlets/space/space-manager.browser.test.d.ts +2 -0
- package/dist/types/src/packlets/space/space-manager.browser.test.d.ts.map +1 -0
- package/dist/types/src/packlets/space/space-manager.d.ts +72 -0
- package/dist/types/src/packlets/space/space-manager.d.ts.map +1 -0
- package/dist/types/src/packlets/space/space-protocol.browser.test.d.ts +2 -0
- package/dist/types/src/packlets/space/space-protocol.browser.test.d.ts.map +1 -0
- package/dist/types/src/packlets/space/space-protocol.d.ts +99 -0
- package/dist/types/src/packlets/space/space-protocol.d.ts.map +1 -0
- package/dist/types/src/packlets/space/space-protocol.test.d.ts +2 -0
- package/dist/types/src/packlets/space/space-protocol.test.d.ts.map +1 -0
- package/dist/types/src/packlets/space/space.d.ts +65 -0
- package/dist/types/src/packlets/space/space.d.ts.map +1 -0
- package/dist/types/src/packlets/space/space.test.d.ts +2 -0
- package/dist/types/src/packlets/space/space.test.d.ts.map +1 -0
- package/dist/types/src/packlets/space/testing/change-metadata.d.ts +8 -0
- package/dist/types/src/packlets/space/testing/change-metadata.d.ts.map +1 -0
- package/dist/types/src/packlets/space/testing/index.d.ts +4 -0
- package/dist/types/src/packlets/space/testing/index.d.ts.map +1 -0
- package/dist/types/src/packlets/space/testing/test-agent-builder.d.ts +62 -0
- package/dist/types/src/packlets/space/testing/test-agent-builder.d.ts.map +1 -0
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts +1 -1
- package/dist/types/src/packlets/space-export/serialized-space-reader.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/serialized-space-writer.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +40 -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 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +25 -23
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/level.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +18 -18
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +7 -6
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts +41 -58
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-session.d.ts +21 -8
- package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +52 -48
- package/src/index.ts +2 -0
- package/src/packlets/agents/edge-agent-manager.ts +56 -15
- package/src/packlets/agents/edge-agent-service.ts +25 -15
- package/src/packlets/devices/devices-service.test.ts +20 -19
- package/src/packlets/devices/devices-service.ts +17 -17
- package/src/packlets/devtools/devtools.ts +133 -75
- package/src/packlets/devtools/feeds.ts +2 -1
- package/src/packlets/devtools/network.ts +42 -12
- package/src/packlets/devtools/spaces.ts +1 -1
- package/src/packlets/diagnostics/diagnostics-broadcast.ts +4 -2
- package/src/packlets/diagnostics/diagnostics-collector.ts +5 -18
- package/src/packlets/diagnostics/diagnostics.ts +0 -11
- package/src/packlets/identity/authenticator.ts +2 -1
- package/src/packlets/identity/contacts-service.ts +46 -37
- package/src/packlets/identity/identity-manager.test.ts +3 -1
- package/src/packlets/identity/identity-manager.ts +73 -5
- package/src/packlets/identity/identity-recovery-manager.ts +56 -7
- package/src/packlets/identity/identity-service.test.ts +27 -18
- package/src/packlets/identity/identity-service.ts +114 -71
- package/src/packlets/identity/identity.test.ts +4 -9
- package/src/packlets/identity/identity.ts +1 -2
- package/src/packlets/invitations/edge-invitation-handler.ts +0 -1
- package/src/packlets/invitations/invitations-handler.ts +39 -3
- package/src/packlets/invitations/invitations-manager.ts +52 -4
- package/src/packlets/invitations/invitations-service.ts +54 -28
- package/src/packlets/logging/logging-service.ts +41 -29
- package/src/packlets/logging/logging.test.ts +28 -15
- package/src/packlets/metadata/index.ts +6 -0
- package/src/packlets/metadata/metadata-store.test.ts +49 -0
- package/src/packlets/metadata/metadata-store.ts +446 -0
- package/src/packlets/metadata/sqlite-metadata-store.ts +409 -0
- package/src/packlets/network/network-service.test.ts +19 -12
- package/src/packlets/network/network-service.ts +96 -29
- package/src/packlets/pipeline/codec.ts +18 -0
- package/src/packlets/pipeline/feeds.ts +22 -0
- package/src/packlets/pipeline/index.ts +8 -0
- package/src/packlets/pipeline/message-selector.ts +35 -0
- package/src/packlets/pipeline/pipeline-stress.test.ts +230 -0
- package/src/packlets/pipeline/pipeline.test.ts +140 -0
- package/src/packlets/pipeline/pipeline.ts +439 -0
- package/src/packlets/pipeline/testing/index.ts +5 -0
- package/src/packlets/pipeline/testing/test-feed-builder.ts +19 -0
- package/src/packlets/pipeline/timeframe-clock.ts +81 -0
- package/src/packlets/services/client-services-layer.ts +186 -0
- package/src/packlets/services/cross-device-space-synchronizer.ts +132 -0
- package/src/packlets/services/effect-rpc.test.ts +314 -0
- package/src/packlets/services/feed-syncer.ts +57 -3
- package/src/packlets/services/index.ts +2 -2
- package/src/packlets/services/platform.ts +0 -6
- package/src/packlets/services/service-context.ts +219 -522
- package/src/packlets/services/service-host.test.ts +34 -11
- package/src/packlets/services/service-host.ts +693 -213
- package/src/packlets/services/spec.md +106 -0
- package/src/packlets/services/sqlite-storage.test.ts +48 -0
- package/src/packlets/services/sqlite-storage.ts +117 -20
- package/src/packlets/space/admission-discovery-extension.ts +91 -0
- package/src/packlets/space/auth.ts +92 -0
- package/src/packlets/space/control-pipeline.test.ts +165 -0
- package/src/packlets/space/control-pipeline.ts +229 -0
- package/src/packlets/space/index.ts +9 -0
- package/src/packlets/space/replication.browser.test.ts +58 -0
- package/src/packlets/space/space-manager.browser.test.ts +40 -0
- package/src/packlets/space/space-manager.ts +224 -0
- package/src/packlets/space/space-protocol.browser.test.ts +129 -0
- package/src/packlets/space/space-protocol.test.ts +158 -0
- package/src/packlets/space/space-protocol.ts +308 -0
- package/src/packlets/space/space.test.ts +181 -0
- package/src/packlets/space/space.ts +196 -0
- package/src/packlets/space/testing/change-metadata.ts +27 -0
- package/src/packlets/space/testing/index.ts +7 -0
- package/src/packlets/space/testing/test-agent-builder.ts +252 -0
- package/src/packlets/space-export/serialized-space-reader.ts +3 -1
- package/src/packlets/space-export/serialized-space-writer.ts +53 -30
- package/src/packlets/space-export/space-archive.test.ts +30 -0
- package/src/packlets/spaces/data-space-manager.test.ts +1 -1
- package/src/packlets/spaces/data-space-manager.ts +148 -33
- package/src/packlets/spaces/data-space.ts +29 -18
- package/src/packlets/spaces/edge-feed-replicator.test.ts +1 -1
- package/src/packlets/spaces/genesis.ts +1 -1
- package/src/packlets/spaces/spaces-service.test.ts +35 -22
- package/src/packlets/spaces/spaces-service.ts +259 -180
- package/src/packlets/storage/level.ts +3 -1
- package/src/packlets/system/system-service.test.ts +31 -13
- package/src/packlets/system/system-service.ts +65 -37
- package/src/packlets/testing/invitation-utils.ts +3 -3
- package/src/packlets/testing/test-builder.ts +35 -20
- package/src/packlets/worker/worker-runtime.ts +222 -260
- package/src/packlets/worker/worker-session.ts +108 -91
- package/src/testing/index.ts +1 -0
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-QCWEHHJW.mjs +0 -24
- package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +0 -7
- package/dist/lib/browser/chunk-XJRPB3GA.mjs +0 -22
- package/dist/lib/browser/chunk-XJRPB3GA.mjs.map +0 -7
- package/dist/lib/browser/chunk-XU5R2BMF.mjs +0 -8837
- package/dist/lib/browser/chunk-XU5R2BMF.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -876
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +0 -88
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +0 -7
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +0 -11
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +0 -7
- package/dist/lib/browser/packlets/locks/browser.mjs +0 -86
- package/dist/lib/browser/packlets/locks/browser.mjs.map +0 -7
- package/dist/lib/browser/packlets/locks/node.mjs +0 -48
- package/dist/lib/browser/packlets/locks/node.mjs.map +0 -7
- package/dist/lib/browser/testing/index.mjs +0 -436
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs +0 -22
- package/dist/lib/node-esm/chunk-2DT3MZRL.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +0 -24
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-H5YTUD35.mjs +0 -8837
- package/dist/lib/node-esm/chunk-H5YTUD35.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -876
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +0 -88
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +0 -7
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +0 -11
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +0 -7
- package/dist/lib/node-esm/packlets/locks/browser.mjs +0 -86
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +0 -7
- package/dist/lib/node-esm/packlets/locks/node.mjs +0 -48
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +0 -7
- package/dist/lib/node-esm/testing/index.mjs +0 -436
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +0 -24
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +0 -1
- package/dist/types/src/packlets/services/service-registry.d.ts +0 -15
- package/dist/types/src/packlets/services/service-registry.d.ts.map +0 -1
- package/dist/types/src/packlets/services/service-registry.test.d.ts +0 -2
- package/dist/types/src/packlets/services/service-registry.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/services/client-rpc-server.ts +0 -111
- package/src/packlets/services/service-registry.test.ts +0 -78
- package/src/packlets/services/service-registry.ts +0 -36
- package/src/testing/setup.ts +0 -11
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import * as EffectContext from 'effect/Context';
|
|
2
|
+
import * as Effect from 'effect/Effect';
|
|
3
|
+
import * as Layer from 'effect/Layer';
|
|
4
|
+
import * as Option from 'effect/Option';
|
|
1
5
|
//
|
|
2
6
|
// Copyright 2022 DXOS.org
|
|
3
7
|
//
|
|
@@ -6,11 +10,11 @@ import platform from 'platform';
|
|
|
6
10
|
import { Event } from '@dxos/async';
|
|
7
11
|
import { Context } from '@dxos/context';
|
|
8
12
|
import { CredentialGenerator, createCredentialSignerWithKey, createDidFromIdentityKey } from '@dxos/credentials';
|
|
9
|
-
import {
|
|
10
|
-
import { type EdgeConnection } from '@dxos/edge-client';
|
|
11
|
-
import { type FeedStore } from '@dxos/feed-store';
|
|
13
|
+
import { failUndefined } from '@dxos/debug';
|
|
14
|
+
import { type EdgeConnection, EdgeConnectionService } from '@dxos/edge-client';
|
|
15
|
+
import { type FeedStore, FeedStoreService } from '@dxos/feed-store';
|
|
12
16
|
import { invariant } from '@dxos/invariant';
|
|
13
|
-
import { type KeyringApi } from '@dxos/keyring';
|
|
17
|
+
import { type KeyringApi, KeyringApiService } from '@dxos/keyring';
|
|
14
18
|
import { PublicKey } from '@dxos/keys';
|
|
15
19
|
import { log } from '@dxos/log';
|
|
16
20
|
import { Device, DeviceKind } from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -29,6 +33,8 @@ import { Timeframe } from '@dxos/timeframe';
|
|
|
29
33
|
import { trace as Trace } from '@dxos/tracing';
|
|
30
34
|
import { deferFunction, isNode, isTauri } from '@dxos/util';
|
|
31
35
|
|
|
36
|
+
import { type IMetadataStore, IMetadataStoreService } from '../metadata';
|
|
37
|
+
import { type SpaceManager, SpaceManagerService, type SwarmIdentity } from '../space';
|
|
32
38
|
import { createAuthProvider } from './authenticator';
|
|
33
39
|
import { Identity } from './identity';
|
|
34
40
|
|
|
@@ -77,8 +83,36 @@ export type IdentityManagerProps = {
|
|
|
77
83
|
devicePresenceOfflineTimeout?: number;
|
|
78
84
|
};
|
|
79
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Resolves the active identity when it becomes available.
|
|
88
|
+
*/
|
|
89
|
+
export type IdentityProvider = () => Identity;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Effect service tag for {@link IdentityProvider}.
|
|
93
|
+
*/
|
|
94
|
+
export class IdentityProviderService extends EffectContext.Tag('@dxos/client-services/IdentityProvider')<
|
|
95
|
+
IdentityProviderService,
|
|
96
|
+
IdentityProvider
|
|
97
|
+
>() {}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Builds an {@link IdentityProvider} from an {@link IdentityManager}.
|
|
101
|
+
*/
|
|
102
|
+
export const identityProviderFromManager =
|
|
103
|
+
(identityManager: IdentityManager): IdentityProvider =>
|
|
104
|
+
() =>
|
|
105
|
+
identityManager.identity ?? failUndefined();
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Effect service tag for {@link IdentityManager}.
|
|
109
|
+
*/
|
|
110
|
+
export class IdentityManagerService extends EffectContext.Tag('@dxos/client-services/IdentityManager')<
|
|
111
|
+
IdentityManagerService,
|
|
112
|
+
IdentityManager
|
|
113
|
+
>() {}
|
|
114
|
+
|
|
80
115
|
// TODO(dmaretskyi): Rename: represents the peer's state machine.
|
|
81
|
-
@Trace.resource()
|
|
82
116
|
export class IdentityManager {
|
|
83
117
|
readonly stateUpdate = new Event();
|
|
84
118
|
|
|
@@ -418,3 +452,37 @@ export class IdentityManager {
|
|
|
418
452
|
});
|
|
419
453
|
}
|
|
420
454
|
}
|
|
455
|
+
|
|
456
|
+
export type IdentityManagerLayerOptions = Pick<
|
|
457
|
+
IdentityManagerProps,
|
|
458
|
+
'devicePresenceAnnounceInterval' | 'devicePresenceOfflineTimeout' | 'edgeFeatures'
|
|
459
|
+
>;
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Effect Layer constructing an {@link IdentityManager} from ambient service dependencies.
|
|
463
|
+
*/
|
|
464
|
+
export const IdentityManagerLayer = (
|
|
465
|
+
options: IdentityManagerLayerOptions = {},
|
|
466
|
+
): Layer.Layer<
|
|
467
|
+
IdentityManagerService,
|
|
468
|
+
never,
|
|
469
|
+
IMetadataStoreService | KeyringApiService | FeedStoreService | SpaceManagerService
|
|
470
|
+
> =>
|
|
471
|
+
Layer.effect(
|
|
472
|
+
IdentityManagerService,
|
|
473
|
+
Effect.gen(function* () {
|
|
474
|
+
const metadataStore = yield* IMetadataStoreService;
|
|
475
|
+
const keyring = yield* KeyringApiService;
|
|
476
|
+
const feedStore = yield* FeedStoreService;
|
|
477
|
+
const spaceManager = yield* SpaceManagerService;
|
|
478
|
+
const edgeConnection = yield* Effect.serviceOption(EdgeConnectionService);
|
|
479
|
+
return new IdentityManager({
|
|
480
|
+
metadataStore,
|
|
481
|
+
keyring,
|
|
482
|
+
feedStore,
|
|
483
|
+
spaceManager,
|
|
484
|
+
edgeConnection: Option.getOrUndefined(edgeConnection),
|
|
485
|
+
...options,
|
|
486
|
+
});
|
|
487
|
+
}),
|
|
488
|
+
);
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as EffectContext from 'effect/Context';
|
|
6
|
+
import * as Effect from 'effect/Effect';
|
|
7
|
+
import * as Layer from 'effect/Layer';
|
|
8
|
+
import * as Option from 'effect/Option';
|
|
9
|
+
|
|
5
10
|
import { type Context } from '@dxos/context';
|
|
6
11
|
import { generateSeedPhrase, keyPairFromSeedPhrase } from '@dxos/credentials';
|
|
7
12
|
import { sign } from '@dxos/crypto';
|
|
8
|
-
import { type EdgeHttpClient } from '@dxos/edge-client';
|
|
13
|
+
import { type EdgeHttpClient, EdgeHttpClientService } from '@dxos/edge-client';
|
|
9
14
|
import { invariant } from '@dxos/invariant';
|
|
10
|
-
import { type KeyringApi } from '@dxos/keyring';
|
|
15
|
+
import { type KeyringApi, KeyringApiService } from '@dxos/keyring';
|
|
11
16
|
import { PublicKey } from '@dxos/keys';
|
|
12
17
|
import { log } from '@dxos/log';
|
|
13
18
|
import {
|
|
@@ -23,16 +28,33 @@ import {
|
|
|
23
28
|
import { Timeframe } from '@dxos/timeframe';
|
|
24
29
|
|
|
25
30
|
import { type Identity } from './identity';
|
|
26
|
-
import { type JoinIdentityProps } from './identity-manager';
|
|
31
|
+
import { IdentityManagerService, type JoinIdentityProps } from './identity-manager';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Effect service tag for {@link EdgeIdentityRecoveryManager}.
|
|
35
|
+
*/
|
|
36
|
+
export class EdgeIdentityRecoveryManagerService extends EffectContext.Tag(
|
|
37
|
+
'@dxos/client-services/EdgeIdentityRecoveryManager',
|
|
38
|
+
)<EdgeIdentityRecoveryManagerService, EdgeIdentityRecoveryManager>() {}
|
|
39
|
+
|
|
40
|
+
export type AcceptRecoveredIdentity = (params: JoinIdentityProps) => Promise<Identity>;
|
|
27
41
|
|
|
28
42
|
export class EdgeIdentityRecoveryManager {
|
|
43
|
+
private _acceptRecoveredIdentity?: AcceptRecoveredIdentity;
|
|
44
|
+
|
|
29
45
|
constructor(
|
|
30
46
|
private readonly _keyring: KeyringApi,
|
|
31
47
|
private readonly _edgeClient: EdgeHttpClient | undefined,
|
|
32
48
|
private readonly _identityProvider: () => Identity | undefined,
|
|
33
|
-
private readonly _acceptRecoveredIdentity: (params: JoinIdentityProps) => Promise<Identity>,
|
|
34
49
|
) {}
|
|
35
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Wires identity acceptance after the composing stack is fully constructed.
|
|
53
|
+
*/
|
|
54
|
+
setAcceptRecoveredIdentity(acceptRecoveredIdentity: AcceptRecoveredIdentity): void {
|
|
55
|
+
this._acceptRecoveredIdentity = acceptRecoveredIdentity;
|
|
56
|
+
}
|
|
57
|
+
|
|
36
58
|
public async createRecoveryCredential({
|
|
37
59
|
data,
|
|
38
60
|
}: CreateRecoveryCredentialRequest): Promise<{ recoveryCode: string | undefined }> {
|
|
@@ -127,7 +149,7 @@ export class EdgeIdentityRecoveryManager {
|
|
|
127
149
|
|
|
128
150
|
const response = await this._edgeClient.recoverIdentity(ctx, request);
|
|
129
151
|
|
|
130
|
-
await this
|
|
152
|
+
await this.#acceptRecoveredIdentity({
|
|
131
153
|
authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
|
|
132
154
|
haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),
|
|
133
155
|
haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),
|
|
@@ -159,7 +181,7 @@ export class EdgeIdentityRecoveryManager {
|
|
|
159
181
|
|
|
160
182
|
const response = await this._edgeClient.recoverIdentity(ctx, request);
|
|
161
183
|
|
|
162
|
-
await this
|
|
184
|
+
await this.#acceptRecoveredIdentity({
|
|
163
185
|
authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
|
|
164
186
|
haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),
|
|
165
187
|
haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),
|
|
@@ -199,7 +221,7 @@ export class EdgeIdentityRecoveryManager {
|
|
|
199
221
|
|
|
200
222
|
log.info('recovering identity', response);
|
|
201
223
|
|
|
202
|
-
await this
|
|
224
|
+
await this.#acceptRecoveredIdentity({
|
|
203
225
|
authorizedDeviceCredential: decodeCredential(response.deviceAuthCredential),
|
|
204
226
|
haloGenesisFeedKey: PublicKey.fromHex(response.genesisFeedKey),
|
|
205
227
|
haloSpaceKey: PublicKey.fromHex(response.haloSpaceKey),
|
|
@@ -209,6 +231,11 @@ export class EdgeIdentityRecoveryManager {
|
|
|
209
231
|
dataFeedKey: await this._keyring.createKey(),
|
|
210
232
|
});
|
|
211
233
|
}
|
|
234
|
+
|
|
235
|
+
#acceptRecoveredIdentity(params: JoinIdentityProps): Promise<Identity> {
|
|
236
|
+
invariant(this._acceptRecoveredIdentity, 'acceptRecoveredIdentity not set');
|
|
237
|
+
return this._acceptRecoveredIdentity(params);
|
|
238
|
+
}
|
|
212
239
|
}
|
|
213
240
|
|
|
214
241
|
const decodeCredential = (credentialBase64: string) => {
|
|
@@ -216,3 +243,25 @@ const decodeCredential = (credentialBase64: string) => {
|
|
|
216
243
|
const codec = schema.getCodecForType('dxos.halo.credentials.Credential');
|
|
217
244
|
return codec.decode(credentialBytes);
|
|
218
245
|
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Effect Layer constructing a dormant {@link EdgeIdentityRecoveryManager}.
|
|
249
|
+
*/
|
|
250
|
+
export const EdgeIdentityRecoveryManagerLayer = (): Layer.Layer<
|
|
251
|
+
EdgeIdentityRecoveryManagerService,
|
|
252
|
+
never,
|
|
253
|
+
KeyringApiService | IdentityManagerService
|
|
254
|
+
> =>
|
|
255
|
+
Layer.effect(
|
|
256
|
+
EdgeIdentityRecoveryManagerService,
|
|
257
|
+
Effect.gen(function* () {
|
|
258
|
+
const keyring = yield* KeyringApiService;
|
|
259
|
+
const edgeClient = yield* Effect.serviceOption(EdgeHttpClientService);
|
|
260
|
+
const identityManager = yield* IdentityManagerService;
|
|
261
|
+
return new EdgeIdentityRecoveryManager(
|
|
262
|
+
keyring,
|
|
263
|
+
Option.getOrUndefined(edgeClient),
|
|
264
|
+
() => identityManager.identity,
|
|
265
|
+
);
|
|
266
|
+
}),
|
|
267
|
+
);
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as Runtime from 'effect/Runtime';
|
|
5
6
|
import { afterEach, beforeEach, describe, expect, onTestFinished, test } from 'vitest';
|
|
6
7
|
|
|
7
8
|
import { Trigger } from '@dxos/async';
|
|
8
9
|
import { Context } from '@dxos/context';
|
|
10
|
+
import { EffectEx } from '@dxos/effect';
|
|
9
11
|
import { PublicKey } from '@dxos/keys';
|
|
10
|
-
import {
|
|
12
|
+
import { subscribeStream } from '@dxos/protocols';
|
|
13
|
+
import { type Identity } from '@dxos/protocols/proto/dxos/client/services';
|
|
11
14
|
|
|
12
15
|
import { type ServiceContext } from '../services';
|
|
13
16
|
import { createServiceContext } from '../testing';
|
|
@@ -15,7 +18,7 @@ import { IdentityServiceImpl } from './identity-service';
|
|
|
15
18
|
|
|
16
19
|
describe('IdentityService', () => {
|
|
17
20
|
let serviceContext: ServiceContext;
|
|
18
|
-
let identityService:
|
|
21
|
+
let identityService: IdentityServiceImpl;
|
|
19
22
|
|
|
20
23
|
beforeEach(async () => {
|
|
21
24
|
serviceContext = await createServiceContext();
|
|
@@ -29,14 +32,16 @@ describe('IdentityService', () => {
|
|
|
29
32
|
|
|
30
33
|
describe('createIdentity', () => {
|
|
31
34
|
test('creates a new identity', async () => {
|
|
32
|
-
const identity = await identityService.createIdentity({});
|
|
35
|
+
const identity = await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
|
|
33
36
|
|
|
34
37
|
expect(identity.identityKey).to.be.instanceof(PublicKey);
|
|
35
38
|
expect(identity.spaceKey).to.be.instanceof(PublicKey);
|
|
36
39
|
});
|
|
37
40
|
|
|
38
41
|
test('creates a new identity with a display name', async () => {
|
|
39
|
-
const identity = await
|
|
42
|
+
const identity = await EffectEx.runPromise(
|
|
43
|
+
identityService['IdentityService.createIdentity']({ profile: { displayName: 'Example' } }),
|
|
44
|
+
);
|
|
40
45
|
|
|
41
46
|
expect(identity.identityKey).to.be.instanceof(PublicKey);
|
|
42
47
|
expect(identity.spaceKey).to.be.instanceof(PublicKey);
|
|
@@ -44,12 +49,14 @@ describe('IdentityService', () => {
|
|
|
44
49
|
});
|
|
45
50
|
|
|
46
51
|
test('fails to create identity if one already exists', async () => {
|
|
47
|
-
await identityService.createIdentity({});
|
|
48
|
-
await expect(identityService.createIdentity({})).rejects.toThrowError(
|
|
52
|
+
await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
|
|
53
|
+
await expect(EffectEx.runPromise(identityService['IdentityService.createIdentity']({}))).rejects.toThrowError(
|
|
54
|
+
'Identity already exists',
|
|
55
|
+
);
|
|
49
56
|
});
|
|
50
57
|
|
|
51
58
|
test('creates identity with no spaces', async () => {
|
|
52
|
-
await identityService.createIdentity({});
|
|
59
|
+
await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
|
|
53
60
|
const dataSpaces = [...(serviceContext.dataSpaceManager?.spaces?.values() ?? [])];
|
|
54
61
|
expect(dataSpaces.length).to.eq(0);
|
|
55
62
|
});
|
|
@@ -59,36 +66,38 @@ describe('IdentityService', () => {
|
|
|
59
66
|
|
|
60
67
|
describe('updateProfile', () => {
|
|
61
68
|
test('updates profile', async () => {
|
|
62
|
-
const identity = await identityService.createIdentity({});
|
|
69
|
+
const identity = await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
|
|
63
70
|
expect(identity.profile?.displayName).to.be.undefined;
|
|
64
71
|
|
|
65
|
-
const updatedIdentity = await
|
|
72
|
+
const updatedIdentity = await EffectEx.runPromise(
|
|
73
|
+
identityService['IdentityService.updateProfile']({ displayName: 'Example' }),
|
|
74
|
+
);
|
|
66
75
|
expect(updatedIdentity.profile?.displayName).to.equal('Example');
|
|
67
76
|
});
|
|
68
77
|
});
|
|
69
78
|
|
|
70
79
|
describe('queryIdentity', () => {
|
|
71
80
|
test('returns undefined if no identity is available', async () => {
|
|
72
|
-
const
|
|
81
|
+
const stream = identityService['IdentityService.queryIdentity']();
|
|
73
82
|
const result = new Trigger<Identity | undefined>();
|
|
74
|
-
|
|
75
|
-
result.wake(identity)
|
|
83
|
+
const cleanup = subscribeStream(Runtime.defaultRuntime, stream, {
|
|
84
|
+
onData: ({ identity }) => result.wake(identity),
|
|
76
85
|
});
|
|
77
|
-
onTestFinished(
|
|
86
|
+
onTestFinished(cleanup);
|
|
78
87
|
expect(await result.wait()).to.be.undefined;
|
|
79
88
|
});
|
|
80
89
|
|
|
81
90
|
test('updates when identity is created', async () => {
|
|
82
|
-
const
|
|
91
|
+
const stream = identityService['IdentityService.queryIdentity']();
|
|
83
92
|
let result = new Trigger<Identity | undefined>();
|
|
84
|
-
|
|
85
|
-
result.wake(identity)
|
|
93
|
+
const cleanup = subscribeStream(Runtime.defaultRuntime, stream, {
|
|
94
|
+
onData: ({ identity }) => result.wake(identity),
|
|
86
95
|
});
|
|
87
|
-
onTestFinished(
|
|
96
|
+
onTestFinished(cleanup);
|
|
88
97
|
expect(await result.wait()).to.be.undefined;
|
|
89
98
|
|
|
90
99
|
result = new Trigger<Identity | undefined>();
|
|
91
|
-
const identity = await identityService.createIdentity({});
|
|
100
|
+
const identity = await EffectEx.runPromise(identityService['IdentityService.createIdentity']({}));
|
|
92
101
|
expect(await result.wait()).to.deep.equal(identity);
|
|
93
102
|
});
|
|
94
103
|
});
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as EffectStream from 'effect/Stream';
|
|
7
|
+
|
|
7
8
|
import { Context, Resource } from '@dxos/context';
|
|
8
9
|
import { createCredential, signPresentation } from '@dxos/credentials';
|
|
9
10
|
import { invariant } from '@dxos/invariant';
|
|
@@ -11,20 +12,22 @@ import { type KeyringApi } from '@dxos/keyring';
|
|
|
11
12
|
import {
|
|
12
13
|
type CreateIdentityRequest,
|
|
13
14
|
type CreateRecoveryCredentialRequest,
|
|
15
|
+
type CreateRecoveryCredentialResponse,
|
|
14
16
|
type Identity as IdentityProto,
|
|
15
|
-
type IdentityService,
|
|
16
17
|
type QueryIdentityResponse,
|
|
17
18
|
type RecoverIdentityRequest,
|
|
19
|
+
type RequestRecoveryChallengeResponse,
|
|
18
20
|
type SignPresentationRequest,
|
|
19
21
|
} from '@dxos/protocols/proto/dxos/client/services';
|
|
20
|
-
import { type Presentation, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
22
|
+
import { type Credential, type Presentation, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
23
|
+
import { type IdentityService } from '@dxos/protocols/rpc';
|
|
21
24
|
|
|
22
25
|
import { type Identity } from './identity';
|
|
23
26
|
import { type CreateIdentityOptions, type IdentityManager } from './identity-manager';
|
|
24
27
|
import { type EdgeIdentityRecoveryManager } from './identity-recovery-manager';
|
|
25
28
|
|
|
26
|
-
export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
27
|
-
constructor(
|
|
29
|
+
export class IdentityServiceImpl extends Resource implements IdentityService.Handlers {
|
|
30
|
+
'constructor'(
|
|
28
31
|
private readonly _identityManager: IdentityManager,
|
|
29
32
|
private readonly _recoveryManager: EdgeIdentityRecoveryManager,
|
|
30
33
|
private readonly _keyring: KeyringApi,
|
|
@@ -34,91 +37,131 @@ export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
|
34
37
|
super();
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
['IdentityService.createIdentity'](request: CreateIdentityRequest): Effect.Effect<IdentityProto, Error> {
|
|
41
|
+
return Effect.tryPromise({
|
|
42
|
+
try: async () => {
|
|
43
|
+
const ctx = Context.default();
|
|
44
|
+
await this._createIdentity({ profile: request.profile, deviceProfile: request.deviceProfile }, ctx);
|
|
45
|
+
return this._getIdentity()!;
|
|
46
|
+
},
|
|
47
|
+
catch: (error) => error as Error,
|
|
48
|
+
});
|
|
41
49
|
}
|
|
42
50
|
|
|
43
|
-
queryIdentity(): Stream<QueryIdentityResponse> {
|
|
44
|
-
return
|
|
45
|
-
|
|
51
|
+
['IdentityService.queryIdentity'](): EffectStream.Stream<QueryIdentityResponse, Error> {
|
|
52
|
+
return EffectStream.async<QueryIdentityResponse, Error>((emit) => {
|
|
53
|
+
// Omit `identity` entirely when absent: an explicit `undefined` would still drive the optional
|
|
54
|
+
// protobuf codec, which dereferences the missing message and throws.
|
|
55
|
+
const emitNext = () => {
|
|
56
|
+
const identity = this._getIdentity();
|
|
57
|
+
void emit.single(identity ? { identity } : {});
|
|
58
|
+
};
|
|
46
59
|
|
|
47
60
|
emitNext();
|
|
48
|
-
|
|
61
|
+
const unsubscribe = this._identityManager.stateUpdate.on(emitNext);
|
|
62
|
+
return Effect.sync(() => unsubscribe());
|
|
49
63
|
});
|
|
50
64
|
}
|
|
51
65
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async updateProfile(profile: ProfileDocument): Promise<IdentityProto> {
|
|
66
|
-
invariant(this._identityManager.identity, 'Identity not initialized.');
|
|
67
|
-
await this._identityManager.updateProfile(profile);
|
|
68
|
-
await this._onProfileUpdate?.(this._identityManager.identity.profileDocument);
|
|
69
|
-
return this._getIdentity()!;
|
|
66
|
+
['IdentityService.updateProfile'](profile: ProfileDocument): Effect.Effect<IdentityProto, Error> {
|
|
67
|
+
return Effect.tryPromise({
|
|
68
|
+
try: async () => {
|
|
69
|
+
invariant(this._identityManager.identity, 'Identity not initialized.');
|
|
70
|
+
await this._identityManager.updateProfile(profile);
|
|
71
|
+
await this._onProfileUpdate?.(this._identityManager.identity.profileDocument);
|
|
72
|
+
return this._getIdentity()!;
|
|
73
|
+
},
|
|
74
|
+
catch: (error) => error as Error,
|
|
75
|
+
});
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
['IdentityService.createRecoveryCredential'](
|
|
79
|
+
request: CreateRecoveryCredentialRequest,
|
|
80
|
+
): Effect.Effect<CreateRecoveryCredentialResponse, Error> {
|
|
81
|
+
return Effect.tryPromise({
|
|
82
|
+
try: async () => this._recoveryManager.createRecoveryCredential(request),
|
|
83
|
+
catch: (error) => error as Error,
|
|
84
|
+
});
|
|
74
85
|
}
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
return
|
|
87
|
+
['IdentityService.requestRecoveryChallenge'](): Effect.Effect<RequestRecoveryChallengeResponse, Error> {
|
|
88
|
+
return Effect.tryPromise({
|
|
89
|
+
try: async () => this._recoveryManager.requestRecoveryChallenge(Context.default()),
|
|
90
|
+
catch: (error) => error as Error,
|
|
91
|
+
});
|
|
78
92
|
}
|
|
79
93
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
['IdentityService.recoverIdentity'](request: RecoverIdentityRequest): Effect.Effect<IdentityProto, Error> {
|
|
95
|
+
return Effect.tryPromise({
|
|
96
|
+
try: async () => {
|
|
97
|
+
const ctx = Context.default();
|
|
98
|
+
if (request.recoveryCode) {
|
|
99
|
+
await this._recoveryManager.recoverIdentity(ctx, { recoveryCode: request.recoveryCode });
|
|
100
|
+
} else if (request.external) {
|
|
101
|
+
await this._recoveryManager.recoverIdentityWithExternalSignature(ctx, request.external);
|
|
102
|
+
} else if (request.token) {
|
|
103
|
+
await this._recoveryManager.recoverIdentityWithToken(ctx, { token: request.token });
|
|
104
|
+
} else if (request.recoveryProof) {
|
|
105
|
+
await this._recoveryManager.recoverIdentityWithToken(ctx, { recoveryProof: request.recoveryProof });
|
|
106
|
+
} else {
|
|
107
|
+
throw new Error('Invalid request.');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return this._getIdentity()!;
|
|
111
|
+
},
|
|
112
|
+
catch: (error) => error as Error,
|
|
113
|
+
});
|
|
95
114
|
}
|
|
96
115
|
|
|
97
116
|
// TODO(burdon): Rename createPresentation?
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
117
|
+
['IdentityService.signPresentation'](request: SignPresentationRequest): Effect.Effect<Presentation, Error> {
|
|
118
|
+
return Effect.tryPromise({
|
|
119
|
+
try: async () => {
|
|
120
|
+
const { presentation, nonce } = request;
|
|
121
|
+
invariant(this._identityManager.identity, 'Identity not initialized.');
|
|
122
|
+
|
|
123
|
+
return await signPresentation({
|
|
124
|
+
presentation,
|
|
125
|
+
signer: this._keyring,
|
|
126
|
+
signerKey: this._identityManager.identity.deviceKey,
|
|
127
|
+
chain: this._identityManager.identity.deviceCredentialChain,
|
|
128
|
+
nonce,
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
catch: (error) => error as Error,
|
|
107
132
|
});
|
|
108
133
|
}
|
|
109
134
|
|
|
110
|
-
|
|
111
|
-
|
|
135
|
+
['IdentityService.createAuthCredential'](): Effect.Effect<Credential, Error> {
|
|
136
|
+
return Effect.tryPromise({
|
|
137
|
+
try: async () => {
|
|
138
|
+
const identity = this._identityManager.identity;
|
|
139
|
+
|
|
140
|
+
invariant(identity, 'Identity not initialized.');
|
|
141
|
+
|
|
142
|
+
return await createCredential({
|
|
143
|
+
assertion: { '@type': 'dxos.halo.credentials.Auth' },
|
|
144
|
+
issuer: identity.identityKey,
|
|
145
|
+
subject: identity.identityKey,
|
|
146
|
+
chain: identity.deviceCredentialChain,
|
|
147
|
+
signingKey: identity.deviceKey,
|
|
148
|
+
signer: this._keyring,
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
catch: (error) => error as Error,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
112
154
|
|
|
113
|
-
|
|
155
|
+
private '_getIdentity'(): IdentityProto | undefined {
|
|
156
|
+
if (!this._identityManager.identity) {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
114
159
|
|
|
115
|
-
return
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
signer: this._keyring,
|
|
122
|
-
});
|
|
160
|
+
return {
|
|
161
|
+
did: this._identityManager.identity.did,
|
|
162
|
+
identityKey: this._identityManager.identity.identityKey,
|
|
163
|
+
spaceKey: this._identityManager.identity.space.key,
|
|
164
|
+
profile: this._identityManager.identity.profileDocument,
|
|
165
|
+
};
|
|
123
166
|
}
|
|
124
167
|
}
|
|
@@ -7,15 +7,7 @@ import { describe, expect, onTestFinished, test } from 'vitest';
|
|
|
7
7
|
import { Event } from '@dxos/async';
|
|
8
8
|
import { Context } from '@dxos/context';
|
|
9
9
|
import { CredentialGenerator, createDidFromIdentityKey, verifyCredential } from '@dxos/credentials';
|
|
10
|
-
import {
|
|
11
|
-
MetadataStore,
|
|
12
|
-
MOCK_AUTH_PROVIDER,
|
|
13
|
-
MOCK_AUTH_VERIFIER,
|
|
14
|
-
Space,
|
|
15
|
-
SpaceProtocol,
|
|
16
|
-
createIdFromSpaceKey,
|
|
17
|
-
valueEncoding,
|
|
18
|
-
} from '@dxos/echo-host';
|
|
10
|
+
import { createIdFromSpaceKey } from '@dxos/echo-protocol';
|
|
19
11
|
import { type EdgeConnection, type MessageListener } from '@dxos/edge-client';
|
|
20
12
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
21
13
|
import { type FeedWrapper } from '@dxos/feed-store';
|
|
@@ -29,6 +21,9 @@ import { AdmittedFeed } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
|
29
21
|
import { StorageType, createStorage } from '@dxos/random-access-storage';
|
|
30
22
|
import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
31
23
|
|
|
24
|
+
import { MetadataStore } from '../metadata';
|
|
25
|
+
import { valueEncoding } from '../pipeline';
|
|
26
|
+
import { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, Space, SpaceProtocol } from '../space';
|
|
32
27
|
import { Identity } from './identity';
|
|
33
28
|
|
|
34
29
|
const createStores = () => {
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
createCredentialSignerWithKey,
|
|
14
14
|
} from '@dxos/credentials';
|
|
15
15
|
import { type Signer } from '@dxos/crypto';
|
|
16
|
-
import { type Space } from '@dxos/echo-host';
|
|
17
16
|
import { type EdgeConnection } from '@dxos/edge-client';
|
|
18
17
|
import { type FeedWrapper, writeMessages } from '@dxos/feed-store';
|
|
19
18
|
import { invariant } from '@dxos/invariant';
|
|
@@ -32,6 +31,7 @@ import { type Presence } from '@dxos/teleport-extension-gossip';
|
|
|
32
31
|
import { trace } from '@dxos/tracing';
|
|
33
32
|
import { type ComplexMap, ComplexSet } from '@dxos/util';
|
|
34
33
|
|
|
34
|
+
import { type Space } from '../space';
|
|
35
35
|
import { EdgeFeedReplicator } from '../spaces';
|
|
36
36
|
import { TrustedKeySetAuthVerifier } from './authenticator';
|
|
37
37
|
|
|
@@ -50,7 +50,6 @@ export type IdentityProps = {
|
|
|
50
50
|
/**
|
|
51
51
|
* Agent identity manager, which includes the agent's Halo space.
|
|
52
52
|
*/
|
|
53
|
-
@trace.resource()
|
|
54
53
|
export class Identity {
|
|
55
54
|
public readonly space: Space;
|
|
56
55
|
private readonly _signer: Signer;
|