@dxos/client-services 0.1.13 → 0.1.14
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/index.mjs +2747 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/node/index.cjs +2823 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/{src → types/src}/index.d.ts +0 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/deprecated/index.d.ts +0 -0
- package/dist/types/src/packlets/deprecated/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/deprecated/invitations.d.ts +4 -4
- package/dist/types/src/packlets/deprecated/invitations.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/deprecated/profile.d.ts +0 -0
- package/dist/types/src/packlets/deprecated/profile.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/deprecated/space.d.ts +0 -0
- package/dist/types/src/packlets/deprecated/space.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/deprecated/system.d.ts +0 -0
- package/dist/types/src/packlets/deprecated/system.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/deprecated/tracing.d.ts +0 -0
- package/dist/types/src/packlets/deprecated/tracing.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/devtools/devtools.d.ts +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/devtools/feeds.d.ts +0 -0
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/devtools/index.d.ts +0 -0
- package/dist/types/src/packlets/devtools/index.d.ts.map +1 -0
- package/dist/types/src/packlets/devtools/keys.d.ts +7 -0
- package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/devtools/network.d.ts +0 -0
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/devtools/spaces.d.ts +0 -0
- package/dist/types/src/packlets/devtools/spaces.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/authenticator.d.ts +0 -0
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/authenticator.test.d.ts +0 -0
- package/dist/types/src/packlets/identity/authenticator.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/devices-service-impl.d.ts +0 -0
- package/dist/types/src/packlets/identity/devices-service-impl.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/identity-manager.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/identity-manager.test.d.ts +0 -0
- package/dist/types/src/packlets/identity/identity-manager.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/identity.d.ts +2 -2
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/identity.test.d.ts +0 -0
- package/dist/types/src/packlets/identity/identity.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/identity/index.d.ts +0 -0
- package/dist/types/src/packlets/identity/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/encoder.d.ts +0 -0
- package/dist/types/src/packlets/invitations/encoder.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/encoder.test.d.ts +0 -0
- package/dist/types/src/packlets/invitations/encoder.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/halo-invitations-handler.d.ts +0 -0
- package/dist/types/src/packlets/invitations/halo-invitations-handler.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/halo-invitations-handler.test.d.ts +0 -0
- package/dist/types/src/packlets/invitations/halo-invitations-handler.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/halo-invitations-proxy.d.ts +0 -0
- package/dist/types/src/packlets/invitations/halo-invitations-proxy.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/halo-invitations-service.d.ts +0 -0
- package/dist/types/src/packlets/invitations/halo-invitations-service.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/halo-invitations-service.test.d.ts +0 -0
- package/dist/types/src/packlets/invitations/halo-invitations-service.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/index.d.ts +0 -0
- package/dist/types/src/packlets/invitations/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/invitations-handler.d.ts +10 -10
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/invitations-proxy.d.ts +0 -0
- package/dist/types/src/packlets/invitations/invitations-proxy.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/invitations-service.d.ts +0 -0
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/invitations.d.ts +0 -0
- package/dist/types/src/packlets/invitations/invitations.d.ts.map +1 -0
- package/dist/types/src/packlets/invitations/rpc-extension.d.ts +17 -0
- package/dist/types/src/packlets/invitations/rpc-extension.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/space-invitations-handler.d.ts +3 -1
- package/dist/types/src/packlets/invitations/space-invitations-handler.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/space-invitations-handler.test.d.ts +0 -0
- package/dist/types/src/packlets/invitations/space-invitations-handler.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/space-invitations-proxy.d.ts +0 -0
- package/dist/types/src/packlets/invitations/space-invitations-proxy.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/space-invitations-service.d.ts +0 -0
- package/dist/types/src/packlets/invitations/space-invitations-service.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/invitations/space-invitations-service.test.d.ts +0 -0
- package/dist/types/src/packlets/invitations/space-invitations-service.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/index.d.ts +0 -0
- package/dist/types/src/packlets/services/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/service-context.d.ts +0 -0
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/service-definitions.d.ts +1 -1
- package/dist/types/src/packlets/services/service-definitions.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/service-host.d.ts +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/service-proxy.d.ts +0 -0
- package/dist/types/src/packlets/services/service-proxy.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/service-registry.d.ts +0 -0
- package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/service-registry.test.d.ts +0 -0
- package/dist/types/src/packlets/services/service-registry.test.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/services/signer.d.ts +0 -0
- package/dist/types/src/packlets/services/signer.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/spaces/index.d.ts +0 -0
- package/dist/types/src/packlets/spaces/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/spaces/spaces-service.d.ts +0 -0
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/storage/index.d.ts +0 -0
- package/dist/types/src/packlets/storage/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/storage/storage.d.ts +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/testing/index.d.ts +0 -0
- package/dist/types/src/packlets/testing/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/testing/test-builder.d.ts +0 -0
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/vault/iframe-runtime.d.ts +1 -1
- package/dist/types/src/packlets/vault/iframe-runtime.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/vault/index.d.ts +0 -0
- package/dist/types/src/packlets/vault/index.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/vault/services.d.ts +2 -2
- package/dist/types/src/packlets/vault/services.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/vault/worker-runtime.d.ts +1 -1
- package/dist/types/src/packlets/vault/worker-runtime.d.ts.map +1 -0
- package/dist/{src → types/src}/packlets/vault/worker-session.d.ts +1 -1
- package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -0
- package/package.json +32 -30
- package/src/packlets/devtools/devtools.ts +2 -1
- package/src/packlets/devtools/keys.ts +19 -0
- package/src/packlets/identity/authenticator.test.ts +5 -8
- package/src/packlets/identity/identity-manager.test.ts +5 -5
- package/src/packlets/identity/identity-manager.ts +6 -4
- package/src/packlets/identity/identity.test.ts +4 -4
- package/src/packlets/identity/identity.ts +1 -1
- package/src/packlets/invitations/encoder.test.ts +3 -2
- package/src/packlets/invitations/halo-invitations-handler.test.ts +5 -5
- package/src/packlets/invitations/halo-invitations-handler.ts +232 -135
- package/src/packlets/invitations/halo-invitations-service.test.ts +4 -4
- package/src/packlets/invitations/invitations-handler.ts +9 -9
- package/src/packlets/invitations/invitations-proxy.ts +1 -1
- package/src/packlets/invitations/invitations-service.ts +1 -1
- package/src/packlets/invitations/invitations.ts +1 -1
- package/src/packlets/invitations/rpc-extension.ts +56 -0
- package/src/packlets/invitations/space-invitations-handler.test.ts +15 -9
- package/src/packlets/invitations/space-invitations-handler.ts +293 -152
- package/src/packlets/invitations/space-invitations-service.test.ts +5 -5
- package/src/packlets/invitations/space-invitations-service.ts +1 -1
- package/src/packlets/services/service-context.ts +6 -1
- package/src/packlets/services/service-registry.test.ts +4 -3
- package/src/packlets/vault/worker-session.ts +8 -3
- package/testing.d.ts +1 -1
- package/testing.js +1 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -27
- package/dist/src/index.js.map +0 -1
- package/dist/src/packlets/deprecated/index.d.ts.map +0 -1
- package/dist/src/packlets/deprecated/index.js +0 -24
- package/dist/src/packlets/deprecated/index.js.map +0 -1
- package/dist/src/packlets/deprecated/invitations.d.ts.map +0 -1
- package/dist/src/packlets/deprecated/invitations.js +0 -12
- package/dist/src/packlets/deprecated/invitations.js.map +0 -1
- package/dist/src/packlets/deprecated/profile.d.ts.map +0 -1
- package/dist/src/packlets/deprecated/profile.js +0 -60
- package/dist/src/packlets/deprecated/profile.js.map +0 -1
- package/dist/src/packlets/deprecated/space.d.ts.map +0 -1
- package/dist/src/packlets/deprecated/space.js +0 -209
- package/dist/src/packlets/deprecated/space.js.map +0 -1
- package/dist/src/packlets/deprecated/system.d.ts.map +0 -1
- package/dist/src/packlets/deprecated/system.js +0 -33
- package/dist/src/packlets/deprecated/system.js.map +0 -1
- package/dist/src/packlets/deprecated/tracing.d.ts.map +0 -1
- package/dist/src/packlets/deprecated/tracing.js +0 -22
- package/dist/src/packlets/deprecated/tracing.js.map +0 -1
- package/dist/src/packlets/devtools/devtools.d.ts.map +0 -1
- package/dist/src/packlets/devtools/devtools.js +0 -88
- package/dist/src/packlets/devtools/devtools.js.map +0 -1
- package/dist/src/packlets/devtools/feeds.d.ts.map +0 -1
- package/dist/src/packlets/devtools/feeds.js +0 -77
- package/dist/src/packlets/devtools/feeds.js.map +0 -1
- package/dist/src/packlets/devtools/index.d.ts.map +0 -1
- package/dist/src/packlets/devtools/index.js +0 -24
- package/dist/src/packlets/devtools/index.js.map +0 -1
- package/dist/src/packlets/devtools/network.d.ts.map +0 -1
- package/dist/src/packlets/devtools/network.js +0 -79
- package/dist/src/packlets/devtools/network.js.map +0 -1
- package/dist/src/packlets/devtools/spaces.d.ts.map +0 -1
- package/dist/src/packlets/devtools/spaces.js +0 -39
- package/dist/src/packlets/devtools/spaces.js.map +0 -1
- package/dist/src/packlets/identity/authenticator.d.ts.map +0 -1
- package/dist/src/packlets/identity/authenticator.js +0 -40
- package/dist/src/packlets/identity/authenticator.js.map +0 -1
- package/dist/src/packlets/identity/authenticator.test.d.ts.map +0 -1
- package/dist/src/packlets/identity/authenticator.test.js +0 -32
- package/dist/src/packlets/identity/authenticator.test.js.map +0 -1
- package/dist/src/packlets/identity/devices-service-impl.d.ts.map +0 -1
- package/dist/src/packlets/identity/devices-service-impl.js +0 -47
- package/dist/src/packlets/identity/devices-service-impl.js.map +0 -1
- package/dist/src/packlets/identity/identity-manager.d.ts.map +0 -1
- package/dist/src/packlets/identity/identity-manager.js +0 -156
- package/dist/src/packlets/identity/identity-manager.js.map +0 -1
- package/dist/src/packlets/identity/identity-manager.test.d.ts.map +0 -1
- package/dist/src/packlets/identity/identity-manager.test.js +0 -88
- package/dist/src/packlets/identity/identity-manager.test.js.map +0 -1
- package/dist/src/packlets/identity/identity.d.ts.map +0 -1
- package/dist/src/packlets/identity/identity.js +0 -133
- package/dist/src/packlets/identity/identity.js.map +0 -1
- package/dist/src/packlets/identity/identity.test.d.ts.map +0 -1
- package/dist/src/packlets/identity/identity.test.js +0 -257
- package/dist/src/packlets/identity/identity.test.js.map +0 -1
- package/dist/src/packlets/identity/index.d.ts.map +0 -1
- package/dist/src/packlets/identity/index.js +0 -23
- package/dist/src/packlets/identity/index.js.map +0 -1
- package/dist/src/packlets/invitations/encoder.d.ts.map +0 -1
- package/dist/src/packlets/invitations/encoder.js +0 -27
- package/dist/src/packlets/invitations/encoder.js.map +0 -1
- package/dist/src/packlets/invitations/encoder.test.d.ts.map +0 -1
- package/dist/src/packlets/invitations/encoder.test.js +0 -19
- package/dist/src/packlets/invitations/encoder.test.js.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-handler.d.ts.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-handler.js +0 -231
- package/dist/src/packlets/invitations/halo-invitations-handler.js.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-handler.test.d.ts.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-handler.test.js +0 -69
- package/dist/src/packlets/invitations/halo-invitations-handler.test.js.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-proxy.d.ts.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-proxy.js +0 -17
- package/dist/src/packlets/invitations/halo-invitations-proxy.js.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-service.d.ts.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-service.js +0 -20
- package/dist/src/packlets/invitations/halo-invitations-service.js.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-service.test.d.ts.map +0 -1
- package/dist/src/packlets/invitations/halo-invitations-service.test.js +0 -83
- package/dist/src/packlets/invitations/halo-invitations-service.test.js.map +0 -1
- package/dist/src/packlets/invitations/index.d.ts.map +0 -1
- package/dist/src/packlets/invitations/index.js +0 -31
- package/dist/src/packlets/invitations/index.js.map +0 -1
- package/dist/src/packlets/invitations/invitations-handler.d.ts.map +0 -1
- package/dist/src/packlets/invitations/invitations-handler.js +0 -18
- package/dist/src/packlets/invitations/invitations-handler.js.map +0 -1
- package/dist/src/packlets/invitations/invitations-proxy.d.ts.map +0 -1
- package/dist/src/packlets/invitations/invitations-proxy.js +0 -121
- package/dist/src/packlets/invitations/invitations-proxy.js.map +0 -1
- package/dist/src/packlets/invitations/invitations-service.d.ts.map +0 -1
- package/dist/src/packlets/invitations/invitations-service.js +0 -174
- package/dist/src/packlets/invitations/invitations-service.js.map +0 -1
- package/dist/src/packlets/invitations/invitations.d.ts.map +0 -1
- package/dist/src/packlets/invitations/invitations.js +0 -59
- package/dist/src/packlets/invitations/invitations.js.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-handler.d.ts.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-handler.js +0 -239
- package/dist/src/packlets/invitations/space-invitations-handler.js.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-handler.test.d.ts.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-handler.test.js +0 -131
- package/dist/src/packlets/invitations/space-invitations-handler.test.js.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-proxy.d.ts.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-proxy.js +0 -17
- package/dist/src/packlets/invitations/space-invitations-proxy.js.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-service.d.ts.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-service.js +0 -31
- package/dist/src/packlets/invitations/space-invitations-service.js.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-service.test.d.ts.map +0 -1
- package/dist/src/packlets/invitations/space-invitations-service.test.js +0 -100
- package/dist/src/packlets/invitations/space-invitations-service.test.js.map +0 -1
- package/dist/src/packlets/services/index.d.ts.map +0 -1
- package/dist/src/packlets/services/index.js +0 -26
- package/dist/src/packlets/services/index.js.map +0 -1
- package/dist/src/packlets/services/service-context.d.ts.map +0 -1
- package/dist/src/packlets/services/service-context.js +0 -103
- package/dist/src/packlets/services/service-context.js.map +0 -1
- package/dist/src/packlets/services/service-definitions.d.ts.map +0 -1
- package/dist/src/packlets/services/service-definitions.js +0 -25
- package/dist/src/packlets/services/service-definitions.js.map +0 -1
- package/dist/src/packlets/services/service-host.d.ts.map +0 -1
- package/dist/src/packlets/services/service-host.js +0 -88
- package/dist/src/packlets/services/service-host.js.map +0 -1
- package/dist/src/packlets/services/service-proxy.d.ts.map +0 -1
- package/dist/src/packlets/services/service-proxy.js +0 -48
- package/dist/src/packlets/services/service-proxy.js.map +0 -1
- package/dist/src/packlets/services/service-registry.d.ts.map +0 -1
- package/dist/src/packlets/services/service-registry.js +0 -24
- package/dist/src/packlets/services/service-registry.js.map +0 -1
- package/dist/src/packlets/services/service-registry.test.d.ts.map +0 -1
- package/dist/src/packlets/services/service-registry.test.js +0 -75
- package/dist/src/packlets/services/service-registry.test.js.map +0 -1
- package/dist/src/packlets/services/signer.d.ts.map +0 -1
- package/dist/src/packlets/services/signer.js +0 -6
- package/dist/src/packlets/services/signer.js.map +0 -1
- package/dist/src/packlets/spaces/index.d.ts.map +0 -1
- package/dist/src/packlets/spaces/index.js +0 -21
- package/dist/src/packlets/spaces/index.js.map +0 -1
- package/dist/src/packlets/spaces/spaces-service.d.ts.map +0 -1
- package/dist/src/packlets/spaces/spaces-service.js +0 -22
- package/dist/src/packlets/spaces/spaces-service.js.map +0 -1
- package/dist/src/packlets/storage/index.d.ts.map +0 -1
- package/dist/src/packlets/storage/index.js +0 -21
- package/dist/src/packlets/storage/index.js.map +0 -1
- package/dist/src/packlets/storage/storage.d.ts.map +0 -1
- package/dist/src/packlets/storage/storage.js +0 -89
- package/dist/src/packlets/storage/storage.js.map +0 -1
- package/dist/src/packlets/testing/index.d.ts.map +0 -1
- package/dist/src/packlets/testing/index.js +0 -21
- package/dist/src/packlets/testing/index.js.map +0 -1
- package/dist/src/packlets/testing/test-builder.d.ts.map +0 -1
- package/dist/src/packlets/testing/test-builder.js +0 -66
- package/dist/src/packlets/testing/test-builder.js.map +0 -1
- package/dist/src/packlets/vault/iframe-runtime.d.ts.map +0 -1
- package/dist/src/packlets/vault/iframe-runtime.js +0 -46
- package/dist/src/packlets/vault/iframe-runtime.js.map +0 -1
- package/dist/src/packlets/vault/index.d.ts.map +0 -1
- package/dist/src/packlets/vault/index.js +0 -23
- package/dist/src/packlets/vault/index.js.map +0 -1
- package/dist/src/packlets/vault/services.d.ts.map +0 -1
- package/dist/src/packlets/vault/services.js +0 -15
- package/dist/src/packlets/vault/services.js.map +0 -1
- package/dist/src/packlets/vault/worker-runtime.d.ts.map +0 -1
- package/dist/src/packlets/vault/worker-runtime.js +0 -99
- package/dist/src/packlets/vault/worker-runtime.js.map +0 -1
- package/dist/src/packlets/vault/worker-session.d.ts.map +0 -1
- package/dist/src/packlets/vault/worker-session.js +0 -106
- package/dist/src/packlets/vault/worker-session.js.map +0 -1
|
@@ -2,29 +2,37 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import assert from 'assert';
|
|
5
|
+
import assert from 'node:assert';
|
|
6
6
|
|
|
7
|
-
import { sleep, Trigger } from '@dxos/async';
|
|
7
|
+
import { scheduleTask, sleep, Trigger } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { generatePasscode } from '@dxos/credentials';
|
|
9
10
|
import { failUndefined } from '@dxos/debug';
|
|
10
11
|
import { PublicKey } from '@dxos/keys';
|
|
11
12
|
import { log } from '@dxos/log';
|
|
12
|
-
import {
|
|
13
|
-
import { createRpcPlugin, RpcPlugin } from '@dxos/protocol-plugin-rpc';
|
|
13
|
+
import { createTeleportProtocolFactory, NetworkManager, StarTopology } from '@dxos/network-manager';
|
|
14
14
|
import { schema } from '@dxos/protocols';
|
|
15
15
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
AuthenticationRequest,
|
|
18
|
+
AuthenticationResponse,
|
|
19
|
+
HaloAdmissionCredentials,
|
|
20
|
+
HaloAdmissionOffer,
|
|
21
|
+
HaloHostService
|
|
22
|
+
} from '@dxos/protocols/proto/dxos/halo/invitations';
|
|
23
|
+
import { ExtensionContext } from '@dxos/teleport';
|
|
17
24
|
|
|
18
25
|
import { IdentityManager } from '../identity';
|
|
19
26
|
import {
|
|
20
27
|
AuthenticatingInvitationProvider,
|
|
28
|
+
AUTHENTICATION_CODE_LENGTH,
|
|
21
29
|
CancellableInvitationObservable,
|
|
22
30
|
InvitationObservableProvider,
|
|
23
|
-
AUTHENTICATION_CODE_LENGTH,
|
|
24
31
|
INVITATION_TIMEOUT,
|
|
25
32
|
ON_CLOSE_DELAY
|
|
26
33
|
} from './invitations';
|
|
27
34
|
import { AbstractInvitationsHandler, InvitationsOptions } from './invitations-handler';
|
|
35
|
+
import { RpcExtension } from './rpc-extension';
|
|
28
36
|
|
|
29
37
|
/**
|
|
30
38
|
* Handles the life-cycle of Halo invitations between peers.
|
|
@@ -43,11 +51,11 @@ export class HaloInvitationsHandler extends AbstractInvitationsHandler {
|
|
|
43
51
|
* Creates an invitation and listens for a join request from the invited (guest) peer.
|
|
44
52
|
*/
|
|
45
53
|
createInvitation(context: void, options?: InvitationsOptions): CancellableInvitationObservable {
|
|
46
|
-
let swarmConnection: SwarmConnection | undefined;
|
|
47
54
|
const { type, timeout = INVITATION_TIMEOUT, swarmKey } = options ?? {};
|
|
48
55
|
assert(type !== Invitation.Type.OFFLINE);
|
|
49
56
|
const identity = this._identityManager.identity ?? failUndefined();
|
|
50
57
|
|
|
58
|
+
// TODO(dmaretskyi): Add invitation kind: halo/space.
|
|
51
59
|
const invitation: Invitation = {
|
|
52
60
|
type,
|
|
53
61
|
invitationId: PublicKey.random().toHex(),
|
|
@@ -55,97 +63,103 @@ export class HaloInvitationsHandler extends AbstractInvitationsHandler {
|
|
|
55
63
|
authenticationCode: generatePasscode(AUTHENTICATION_CODE_LENGTH)
|
|
56
64
|
};
|
|
57
65
|
|
|
66
|
+
const ctx = new Context({
|
|
67
|
+
onError: (err) => {
|
|
68
|
+
void ctx.dispose();
|
|
69
|
+
observable.callback.onError(err);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
58
73
|
// TODO(burdon): Stop anything pending.
|
|
59
74
|
const observable = new InvitationObservableProvider(async () => {
|
|
60
|
-
await
|
|
75
|
+
await ctx.dispose();
|
|
61
76
|
});
|
|
62
77
|
|
|
63
78
|
let authenticationCode: string;
|
|
64
79
|
const complete = new Trigger<PublicKey>();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
80
|
+
|
|
81
|
+
// Called for every connecting peer.
|
|
82
|
+
const createExtension = (): HostHaloInvitationExtension => {
|
|
83
|
+
const hostInvitationExtension = new HostHaloInvitationExtension({
|
|
84
|
+
requestAdmission: async () => {
|
|
85
|
+
log('responding with admission offer', {
|
|
86
|
+
host: identity.deviceKey
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// TODO(burdon): Is this the right place to set this state?
|
|
90
|
+
observable.callback.onAuthenticating?.(invitation);
|
|
91
|
+
return {
|
|
92
|
+
identityKey: identity.identityKey,
|
|
93
|
+
haloSpaceKey: identity.haloSpaceKey,
|
|
94
|
+
genesisFeedKey: identity.haloGenesisFeedKey
|
|
95
|
+
};
|
|
69
96
|
},
|
|
70
|
-
handlers: {
|
|
71
|
-
HaloHostService: {
|
|
72
|
-
requestAdmission: async () => {
|
|
73
|
-
log('responding with admission offer', {
|
|
74
|
-
host: identity.deviceKey
|
|
75
|
-
});
|
|
76
97
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
authenticationCode
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// TODO(burdon): Not used: controlFeedKey, dataFeedKey.
|
|
92
|
-
presentAdmissionCredentials: async (credentials) => {
|
|
93
|
-
try {
|
|
94
|
-
// Check authenticated.
|
|
95
|
-
if (invitation.type === undefined || invitation.type === Invitation.Type.INTERACTIVE) {
|
|
96
|
-
if (
|
|
97
|
-
invitation.authenticationCode === undefined ||
|
|
98
|
-
authenticationCode !== invitation.authenticationCode
|
|
99
|
-
) {
|
|
100
|
-
throw new Error('authentication code not set');
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
log('writing guest credentials', { host: identity.deviceKey, guest: credentials.deviceKey });
|
|
105
|
-
// TODO(burdon): Check if already admitted.
|
|
106
|
-
await identity.admitDevice(credentials);
|
|
107
|
-
|
|
108
|
-
// Updating credentials complete.
|
|
109
|
-
complete.wake(credentials.deviceKey);
|
|
110
|
-
} catch (err) {
|
|
111
|
-
// TODO(burdon): Generic RPC callback to report error to client.
|
|
112
|
-
observable.callback.onError(err);
|
|
113
|
-
throw err; // Propagate error to guest.
|
|
98
|
+
authenticate: async ({ authenticationCode: code }) => {
|
|
99
|
+
log('received authentication request', { authenticationCode: code });
|
|
100
|
+
authenticationCode = code;
|
|
101
|
+
return { status: AuthenticationResponse.Status.OK };
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
// TODO(burdon): Not used: controlFeedKey, dataFeedKey.
|
|
105
|
+
presentAdmissionCredentials: async (credentials) => {
|
|
106
|
+
try {
|
|
107
|
+
// Check authenticated.
|
|
108
|
+
if (invitation.type !== Invitation.Type.INTERACTIVE_TESTING) {
|
|
109
|
+
if (invitation.authenticationCode === undefined || invitation.authenticationCode !== authenticationCode) {
|
|
110
|
+
throw new Error(`invalid authentication code: ${authenticationCode}`);
|
|
114
111
|
}
|
|
115
112
|
}
|
|
113
|
+
|
|
114
|
+
log('writing guest credentials', { host: identity.deviceKey, guest: credentials.deviceKey });
|
|
115
|
+
// TODO(burdon): Check if already admitted.
|
|
116
|
+
await identity.admitDevice(credentials);
|
|
117
|
+
|
|
118
|
+
// Updating credentials complete.
|
|
119
|
+
complete.wake(credentials.deviceKey);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
// TODO(burdon): Generic RPC callback to report error to client.
|
|
122
|
+
observable.callback.onError(err);
|
|
123
|
+
throw err; // Propagate error to guest.
|
|
116
124
|
}
|
|
117
125
|
},
|
|
118
|
-
port
|
|
119
|
-
});
|
|
120
126
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
onOpen: () => {
|
|
128
|
+
scheduleTask(ctx, async () => {
|
|
129
|
+
try {
|
|
130
|
+
log('connected', { host: identity.deviceKey });
|
|
131
|
+
observable.callback.onConnected?.(invitation);
|
|
132
|
+
const deviceKey = await complete.wait({ timeout });
|
|
133
|
+
log('admitted guest', { host: identity.deviceKey, guest: deviceKey });
|
|
134
|
+
observable.callback.onSuccess(invitation);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
if (!observable.cancelled) {
|
|
137
|
+
log.error('failed', err);
|
|
138
|
+
observable.callback.onError(err);
|
|
139
|
+
}
|
|
140
|
+
} finally {
|
|
141
|
+
// NOTE: If we close immediately after `complete` trigger finishes, Guest won't receive the reply to the last RPC.
|
|
142
|
+
// TODO(dmaretskyi): Implement a soft-close which waits for the last connection to terminate before closing.
|
|
143
|
+
await sleep(ON_CLOSE_DELAY);
|
|
144
|
+
await ctx.dispose();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
132
147
|
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
await swarmConnection!.close();
|
|
137
|
-
}
|
|
138
|
-
});
|
|
148
|
+
});
|
|
149
|
+
return hostInvitationExtension;
|
|
150
|
+
};
|
|
139
151
|
|
|
140
|
-
|
|
152
|
+
scheduleTask(ctx, async () => {
|
|
141
153
|
const topic = invitation.swarmKey!;
|
|
142
|
-
const
|
|
143
|
-
swarmConnection = await this._networkManager.joinSwarm({
|
|
154
|
+
const swarmConnection = await this._networkManager.joinSwarm({
|
|
144
155
|
topic,
|
|
145
156
|
peerId: topic,
|
|
146
|
-
|
|
157
|
+
protocolProvider: createTeleportProtocolFactory(async (teleport) => {
|
|
158
|
+
teleport.addExtension('dxos.halo.invitations', createExtension());
|
|
159
|
+
}),
|
|
147
160
|
topology: new StarTopology(topic)
|
|
148
161
|
});
|
|
162
|
+
ctx.onDispose(() => swarmConnection.close());
|
|
149
163
|
|
|
150
164
|
observable.callback.onConnecting?.(invitation);
|
|
151
165
|
});
|
|
@@ -160,12 +174,18 @@ export class HaloInvitationsHandler extends AbstractInvitationsHandler {
|
|
|
160
174
|
*/
|
|
161
175
|
acceptInvitation(invitation: Invitation, options?: InvitationsOptions): AuthenticatingInvitationProvider {
|
|
162
176
|
const { timeout = INVITATION_TIMEOUT } = options ?? {};
|
|
163
|
-
|
|
177
|
+
|
|
178
|
+
const ctx = new Context({
|
|
179
|
+
onError: (err) => {
|
|
180
|
+
void ctx.dispose();
|
|
181
|
+
observable.callback.onError(err);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
164
184
|
|
|
165
185
|
const authenticated = new Trigger<string>();
|
|
166
186
|
const observable = new AuthenticatingInvitationProvider({
|
|
167
187
|
onCancel: async () => {
|
|
168
|
-
await
|
|
188
|
+
await ctx.dispose();
|
|
169
189
|
},
|
|
170
190
|
|
|
171
191
|
// TODO(burdon): Consider retry.
|
|
@@ -176,80 +196,157 @@ export class HaloInvitationsHandler extends AbstractInvitationsHandler {
|
|
|
176
196
|
|
|
177
197
|
let connectionCount = 0;
|
|
178
198
|
const complete = new Trigger<PublicKey>();
|
|
179
|
-
const plugin = createRpcPlugin(async (port) => {
|
|
180
|
-
const peer = createProtoRpcPeer({
|
|
181
|
-
requested: {
|
|
182
|
-
HaloHostService: schema.getService('dxos.halo.invitations.HaloHostService')
|
|
183
|
-
},
|
|
184
|
-
port
|
|
185
|
-
});
|
|
186
199
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
const createExtension = (): GuestHaloInvitationExtension => {
|
|
201
|
+
const extension = new GuestHaloInvitationExtension({
|
|
202
|
+
onOpen: () => {
|
|
203
|
+
scheduleTask(ctx, async () => {
|
|
204
|
+
try {
|
|
205
|
+
// TODO(burdon): Bug where guest may create multiple connections.
|
|
206
|
+
if (++connectionCount > 1) {
|
|
207
|
+
throw new Error(`multiple connections detected: ${connectionCount}`);
|
|
208
|
+
}
|
|
193
209
|
|
|
194
|
-
|
|
195
|
-
|
|
210
|
+
log('connected');
|
|
211
|
+
observable.callback.onConnected?.(invitation);
|
|
196
212
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
213
|
+
// 1. Send request.
|
|
214
|
+
log('sending admission request');
|
|
215
|
+
const { identityKey, haloSpaceKey, genesisFeedKey } =
|
|
216
|
+
await extension.rpc.HaloHostService.requestAdmission();
|
|
200
217
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
218
|
+
// 2. Get authentication code.
|
|
219
|
+
// TODO(burdon): Test timeout (options for timeouts at different steps).
|
|
220
|
+
if (invitation.type === undefined || invitation.type === Invitation.Type.INTERACTIVE) {
|
|
221
|
+
log('guest waiting for authentication code...');
|
|
222
|
+
observable.callback.onAuthenticating?.(invitation);
|
|
223
|
+
const authenticationCode = await authenticated.wait({ timeout });
|
|
224
|
+
log('sending authentication request');
|
|
225
|
+
await extension.rpc.HaloHostService.authenticate({ authenticationCode });
|
|
226
|
+
}
|
|
210
227
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
// 3. Create local identity.
|
|
229
|
+
// TODO(burdon): Abandon if does not complete (otherwise retry will fail).
|
|
230
|
+
const identity = await this._identityManager.acceptIdentity({
|
|
231
|
+
identityKey,
|
|
232
|
+
haloSpaceKey,
|
|
233
|
+
haloGenesisFeedKey: genesisFeedKey
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// 4. Send admission credentials to host (with local identity keys).
|
|
237
|
+
log('presenting admission credentials', { guest: identity.deviceKey, identityKey });
|
|
238
|
+
await extension.rpc.HaloHostService.presentAdmissionCredentials(identity.getAdmissionCredentials());
|
|
239
|
+
|
|
240
|
+
// 5. Success.
|
|
241
|
+
log('admitted by host', { guest: identity.deviceKey, identityKey });
|
|
242
|
+
complete.wake(identityKey);
|
|
243
|
+
} catch (err) {
|
|
244
|
+
if (!observable.cancelled) {
|
|
245
|
+
log.warn('auth failed', err);
|
|
246
|
+
observable.callback.onError(err);
|
|
247
|
+
}
|
|
248
|
+
} finally {
|
|
249
|
+
await ctx.dispose();
|
|
250
|
+
}
|
|
251
|
+
});
|
|
230
252
|
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
});
|
|
253
|
+
});
|
|
254
|
+
return extension;
|
|
255
|
+
};
|
|
235
256
|
|
|
236
|
-
|
|
257
|
+
scheduleTask(ctx, async () => {
|
|
237
258
|
assert(invitation.swarmKey);
|
|
238
259
|
const topic = invitation.swarmKey;
|
|
239
|
-
const
|
|
240
|
-
swarmConnection = await this._networkManager.joinSwarm({
|
|
260
|
+
const swarmConnection = await this._networkManager.joinSwarm({
|
|
241
261
|
topic,
|
|
242
262
|
peerId: PublicKey.random(),
|
|
243
|
-
|
|
263
|
+
protocolProvider: createTeleportProtocolFactory(async (teleport) => {
|
|
264
|
+
teleport.addExtension('dxos.halo.invitations', createExtension());
|
|
265
|
+
}),
|
|
244
266
|
topology: new StarTopology(topic)
|
|
245
267
|
});
|
|
268
|
+
ctx.onDispose(() => swarmConnection.close());
|
|
246
269
|
|
|
247
270
|
observable.callback.onConnecting?.(invitation);
|
|
248
271
|
invitation.identityKey = await complete.wait();
|
|
249
272
|
observable.callback.onSuccess(invitation);
|
|
250
|
-
await
|
|
273
|
+
await ctx.dispose();
|
|
251
274
|
});
|
|
252
275
|
|
|
253
276
|
return observable;
|
|
254
277
|
}
|
|
255
278
|
}
|
|
279
|
+
|
|
280
|
+
type HostHaloInvitationExtensionCallbacks = {
|
|
281
|
+
requestAdmission: () => Promise<HaloAdmissionOffer>;
|
|
282
|
+
authenticate: (request: AuthenticationRequest) => Promise<AuthenticationResponse>;
|
|
283
|
+
presentAdmissionCredentials: (request: HaloAdmissionCredentials) => Promise<void>;
|
|
284
|
+
// Deliberately not async to not block the extensions opening.
|
|
285
|
+
onOpen: () => void;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Host's side for a connection to a concrete peer in p2p network during invitation.
|
|
290
|
+
*/
|
|
291
|
+
class HostHaloInvitationExtension extends RpcExtension<{}, { HaloHostService: HaloHostService }> {
|
|
292
|
+
constructor(private readonly _callbacks: HostHaloInvitationExtensionCallbacks) {
|
|
293
|
+
super({
|
|
294
|
+
exposed: {
|
|
295
|
+
HaloHostService: schema.getService('dxos.halo.invitations.HaloHostService')
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
protected override async getHandlers(): Promise<{ HaloHostService: HaloHostService }> {
|
|
301
|
+
return {
|
|
302
|
+
// TODO(dmaretskyi): For now this is just forwarding the data to callbacks since we don't have session-specific logic.
|
|
303
|
+
// Perhaps in the future we will have more complex logic here.
|
|
304
|
+
HaloHostService: {
|
|
305
|
+
requestAdmission: async () => {
|
|
306
|
+
return this._callbacks.requestAdmission();
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
authenticate: async (credentials) => {
|
|
310
|
+
return this._callbacks.authenticate(credentials);
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
// TODO(burdon): Not used: controlFeedKey, dataFeedKey.
|
|
314
|
+
presentAdmissionCredentials: async (credentials) => {
|
|
315
|
+
return this._callbacks.presentAdmissionCredentials(credentials);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
override async onOpen(context: ExtensionContext) {
|
|
322
|
+
await super.onOpen(context);
|
|
323
|
+
this._callbacks.onOpen();
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
type GuestHaloInvitationExtensionCallbacks = {
|
|
328
|
+
// Deliberately not async to not block the extensions opening.
|
|
329
|
+
onOpen: () => void;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Guest's side for a connection to a concrete peer in p2p network during invitation.
|
|
334
|
+
*/
|
|
335
|
+
class GuestHaloInvitationExtension extends RpcExtension<{ HaloHostService: HaloHostService }, {}> {
|
|
336
|
+
constructor(private readonly _callbacks: GuestHaloInvitationExtensionCallbacks) {
|
|
337
|
+
super({
|
|
338
|
+
requested: {
|
|
339
|
+
HaloHostService: schema.getService('dxos.halo.invitations.HaloHostService')
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
protected override async getHandlers() {
|
|
345
|
+
return {};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
override async onOpen(context: ExtensionContext) {
|
|
349
|
+
await super.onOpen(context);
|
|
350
|
+
this._callbacks.onOpen();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import assert from 'assert';
|
|
6
5
|
import { expect } from 'chai';
|
|
6
|
+
import assert from 'node:assert';
|
|
7
7
|
import waitForExpect from 'wait-for-expect';
|
|
8
8
|
|
|
9
9
|
import { asyncChain, Trigger } from '@dxos/async';
|
|
10
10
|
import { raise } from '@dxos/debug';
|
|
11
11
|
import { Invitation, HaloInvitationsService } from '@dxos/protocols/proto/dxos/client/services';
|
|
12
|
-
import { afterTest } from '@dxos/
|
|
12
|
+
import { describe, test, afterTest } from '@dxos/test';
|
|
13
13
|
|
|
14
14
|
import { ServiceContext } from '../services';
|
|
15
15
|
import { createPeers } from '../testing';
|
|
@@ -21,8 +21,8 @@ const closeAfterTest = async (peer: ServiceContext) => {
|
|
|
21
21
|
return peer;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
describe('services/halo-invitation-service',
|
|
25
|
-
|
|
24
|
+
describe('services/halo-invitation-service', () => {
|
|
25
|
+
test('creates identity and invites peer', async () => {
|
|
26
26
|
const [host, guest] = await asyncChain<ServiceContext>([closeAfterTest])(createPeers(2));
|
|
27
27
|
|
|
28
28
|
await host.identityManager.createIdentity();
|
|
@@ -20,26 +20,26 @@ export type InvitationsOptions = {
|
|
|
20
20
|
* Handles the life-cycle of Space invitations between peers.
|
|
21
21
|
*
|
|
22
22
|
* Host
|
|
23
|
-
* - Creates an invitation containing a swarm topic.
|
|
23
|
+
* - Creates an invitation containing a swarm topic (which can be shared via a URL, QR code, or direct message).
|
|
24
24
|
* - Joins the swarm with the topic and waits for guest's admission request.
|
|
25
|
-
* -
|
|
25
|
+
* - Wait for guest to authenticate with OTP.
|
|
26
|
+
* - Waits for guest to present credentials (containing local device and feed keys).
|
|
26
27
|
* - Writes credentials to control feed then exits.
|
|
27
28
|
*
|
|
28
29
|
* Guest
|
|
29
30
|
* - Joins the swarm with the topic.
|
|
30
|
-
* - NOTE: The topic is transmitted out-of-band (e.g., via a QR code).
|
|
31
31
|
* - Sends an admission request.
|
|
32
|
+
* - Sends authentication OTP.
|
|
32
33
|
* - If Space handler then creates a local cloned space (with genesis block).
|
|
33
|
-
* - Sends admission credentials
|
|
34
|
+
* - Sends admission credentials.
|
|
34
35
|
*
|
|
35
36
|
* TODO(burdon): Show proxy/service relationship and reference design doc/diagram.
|
|
36
37
|
*
|
|
37
38
|
* ```
|
|
38
|
-
* [Guest]
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* |--------------------------PresentAdmissionCredentials-->|
|
|
39
|
+
* [Guest] [Host]
|
|
40
|
+
* |-----------------------------RequestAdmission-->|
|
|
41
|
+
* |-------------------------------[Authenticate]-->|
|
|
42
|
+
* |------------------PresentAdmissionCredentials-->|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
export interface InvitationsHandler<T = void> {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { createProtoRpcPeer, ProtoRpcPeer, ProtoRpcPeerOptions } from '@dxos/rpc';
|
|
6
|
+
import { ExtensionContext, TeleportExtension } from '@dxos/teleport';
|
|
7
|
+
|
|
8
|
+
export abstract class RpcExtension<Client, Server> implements TeleportExtension {
|
|
9
|
+
private _extensionContext!: ExtensionContext;
|
|
10
|
+
private _rpc!: ProtoRpcPeer<Client>;
|
|
11
|
+
|
|
12
|
+
constructor(private readonly _params: Omit<ProtoRpcPeerOptions<Client, Server>, 'port' | 'handlers'>) {}
|
|
13
|
+
|
|
14
|
+
get initiator() {
|
|
15
|
+
return this._extensionContext.initiator;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get localPeerId() {
|
|
19
|
+
return this._extensionContext.localPeerId;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get remotePeerId() {
|
|
23
|
+
return this._extensionContext.remotePeerId;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get rpc(): Client {
|
|
27
|
+
return this._rpc.rpc;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected abstract getHandlers(): Promise<Server>;
|
|
31
|
+
|
|
32
|
+
async onOpen(context: ExtensionContext): Promise<void> {
|
|
33
|
+
this._extensionContext = context;
|
|
34
|
+
|
|
35
|
+
const handlers = await this.getHandlers();
|
|
36
|
+
|
|
37
|
+
const port = context.createPort('rpc', {
|
|
38
|
+
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
39
|
+
});
|
|
40
|
+
this._rpc = createProtoRpcPeer({
|
|
41
|
+
...this._params,
|
|
42
|
+
handlers,
|
|
43
|
+
port
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await this._rpc.open();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async onClose(err?: Error | undefined): Promise<void> {
|
|
50
|
+
await this._rpc.close();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
close() {
|
|
54
|
+
this._extensionContext.close();
|
|
55
|
+
}
|
|
56
|
+
}
|