@weaveprotocol/core 0.1.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/README.md +1106 -0
- package/dist/elements/auth-styles.d.ts +18 -0
- package/dist/elements/auth-styles.d.ts.map +1 -0
- package/dist/elements/auth-styles.js +150 -0
- package/dist/elements/auth-styles.js.map +1 -0
- package/dist/elements/dom.d.ts +28 -0
- package/dist/elements/dom.d.ts.map +1 -0
- package/dist/elements/dom.js +74 -0
- package/dist/elements/dom.js.map +1 -0
- package/dist/elements/index.d.ts +13 -0
- package/dist/elements/index.d.ts.map +1 -0
- package/dist/elements/index.js +11 -0
- package/dist/elements/index.js.map +1 -0
- package/dist/elements/weave-auth.d.ts +52 -0
- package/dist/elements/weave-auth.d.ts.map +1 -0
- package/dist/elements/weave-auth.js +427 -0
- package/dist/elements/weave-auth.js.map +1 -0
- package/dist/identity/account-store.d.ts +113 -0
- package/dist/identity/account-store.d.ts.map +1 -0
- package/dist/identity/account-store.js +305 -0
- package/dist/identity/account-store.js.map +1 -0
- package/dist/identity/account-vault.d.ts +199 -0
- package/dist/identity/account-vault.d.ts.map +1 -0
- package/dist/identity/account-vault.js +251 -0
- package/dist/identity/account-vault.js.map +1 -0
- package/dist/identity/agent-note.d.ts +19 -0
- package/dist/identity/agent-note.d.ts.map +1 -0
- package/dist/identity/agent-note.js +29 -0
- package/dist/identity/agent-note.js.map +1 -0
- package/dist/identity/crypto-p256.d.ts +7 -0
- package/dist/identity/crypto-p256.d.ts.map +1 -0
- package/dist/identity/crypto-p256.js +84 -0
- package/dist/identity/crypto-p256.js.map +1 -0
- package/dist/identity/device-key.d.ts +60 -0
- package/dist/identity/device-key.d.ts.map +1 -0
- package/dist/identity/device-key.js +103 -0
- package/dist/identity/device-key.js.map +1 -0
- package/dist/identity/did.d.ts +22 -0
- package/dist/identity/did.d.ts.map +1 -0
- package/dist/identity/did.js +37 -0
- package/dist/identity/did.js.map +1 -0
- package/dist/identity/folder-account.d.ts +65 -0
- package/dist/identity/folder-account.d.ts.map +1 -0
- package/dist/identity/folder-account.js +115 -0
- package/dist/identity/folder-account.js.map +1 -0
- package/dist/identity/identity-manager.d.ts +36 -0
- package/dist/identity/identity-manager.d.ts.map +1 -0
- package/dist/identity/identity-manager.js +115 -0
- package/dist/identity/identity-manager.js.map +1 -0
- package/dist/identity/index.d.ts +10 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +10 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/keys.d.ts +24 -0
- package/dist/identity/keys.d.ts.map +1 -0
- package/dist/identity/keys.js +38 -0
- package/dist/identity/keys.js.map +1 -0
- package/dist/identity/pairing.d.ts +83 -0
- package/dist/identity/pairing.d.ts.map +1 -0
- package/dist/identity/pairing.js +120 -0
- package/dist/identity/pairing.js.map +1 -0
- package/dist/identity/passkey-diagnostics.d.ts +54 -0
- package/dist/identity/passkey-diagnostics.d.ts.map +1 -0
- package/dist/identity/passkey-diagnostics.js +178 -0
- package/dist/identity/passkey-diagnostics.js.map +1 -0
- package/dist/identity/recovery-code.d.ts +50 -0
- package/dist/identity/recovery-code.d.ts.map +1 -0
- package/dist/identity/recovery-code.js +116 -0
- package/dist/identity/recovery-code.js.map +1 -0
- package/dist/identity/root-signer.d.ts +59 -0
- package/dist/identity/root-signer.d.ts.map +1 -0
- package/dist/identity/root-signer.js +44 -0
- package/dist/identity/root-signer.js.map +1 -0
- package/dist/identity/ucan.d.ts +164 -0
- package/dist/identity/ucan.d.ts.map +1 -0
- package/dist/identity/ucan.js +273 -0
- package/dist/identity/ucan.js.map +1 -0
- package/dist/identity/webauthn.d.ts +87 -0
- package/dist/identity/webauthn.d.ts.map +1 -0
- package/dist/identity/webauthn.js +155 -0
- package/dist/identity/webauthn.js.map +1 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/network/index.d.ts +17 -0
- package/dist/network/index.d.ts.map +1 -0
- package/dist/network/index.js +10 -0
- package/dist/network/index.js.map +1 -0
- package/dist/network/introductions.d.ts +85 -0
- package/dist/network/introductions.d.ts.map +1 -0
- package/dist/network/introductions.js +94 -0
- package/dist/network/introductions.js.map +1 -0
- package/dist/network/local-transport.d.ts +22 -0
- package/dist/network/local-transport.d.ts.map +1 -0
- package/dist/network/local-transport.js +55 -0
- package/dist/network/local-transport.js.map +1 -0
- package/dist/network/mesh.d.ts +31 -0
- package/dist/network/mesh.d.ts.map +1 -0
- package/dist/network/mesh.js +332 -0
- package/dist/network/mesh.js.map +1 -0
- package/dist/network/multi-signaling.d.ts +29 -0
- package/dist/network/multi-signaling.d.ts.map +1 -0
- package/dist/network/multi-signaling.js +125 -0
- package/dist/network/multi-signaling.js.map +1 -0
- package/dist/network/network-manager.d.ts +37 -0
- package/dist/network/network-manager.d.ts.map +1 -0
- package/dist/network/network-manager.js +64 -0
- package/dist/network/network-manager.js.map +1 -0
- package/dist/network/peer-auth.d.ts +98 -0
- package/dist/network/peer-auth.d.ts.map +1 -0
- package/dist/network/peer-auth.js +86 -0
- package/dist/network/peer-auth.js.map +1 -0
- package/dist/network/rtc-transport.d.ts +18 -0
- package/dist/network/rtc-transport.d.ts.map +1 -0
- package/dist/network/rtc-transport.js +149 -0
- package/dist/network/rtc-transport.js.map +1 -0
- package/dist/network/signaling.d.ts +40 -0
- package/dist/network/signaling.d.ts.map +1 -0
- package/dist/network/signaling.js +124 -0
- package/dist/network/signaling.js.map +1 -0
- package/dist/network/transport.d.ts +50 -0
- package/dist/network/transport.d.ts.map +1 -0
- package/dist/network/transport.js +13 -0
- package/dist/network/transport.js.map +1 -0
- package/dist/network/ws-transport.d.ts +42 -0
- package/dist/network/ws-transport.d.ts.map +1 -0
- package/dist/network/ws-transport.js +194 -0
- package/dist/network/ws-transport.js.map +1 -0
- package/dist/node/actions.d.ts +62 -0
- package/dist/node/actions.d.ts.map +1 -0
- package/dist/node/actions.js +500 -0
- package/dist/node/actions.js.map +1 -0
- package/dist/node/carrier.d.ts +85 -0
- package/dist/node/carrier.d.ts.map +1 -0
- package/dist/node/carrier.js +192 -0
- package/dist/node/carrier.js.map +1 -0
- package/dist/node/copy.d.ts +38 -0
- package/dist/node/copy.d.ts.map +1 -0
- package/dist/node/copy.js +53 -0
- package/dist/node/copy.js.map +1 -0
- package/dist/node/index.d.ts +16 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +11 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/node.d.ts +12 -0
- package/dist/node/node.d.ts.map +1 -0
- package/dist/node/node.js +872 -0
- package/dist/node/node.js.map +1 -0
- package/dist/node/space-runtime.d.ts +144 -0
- package/dist/node/space-runtime.d.ts.map +1 -0
- package/dist/node/space-runtime.js +1221 -0
- package/dist/node/space-runtime.js.map +1 -0
- package/dist/node/stores.d.ts +45 -0
- package/dist/node/stores.d.ts.map +1 -0
- package/dist/node/stores.js +31 -0
- package/dist/node/stores.js.map +1 -0
- package/dist/node/types.d.ts +508 -0
- package/dist/node/types.d.ts.map +1 -0
- package/dist/node/types.js +2 -0
- package/dist/node/types.js.map +1 -0
- package/dist/privacy/index.d.ts +4 -0
- package/dist/privacy/index.d.ts.map +1 -0
- package/dist/privacy/index.js +4 -0
- package/dist/privacy/index.js.map +1 -0
- package/dist/privacy/key-distribution.d.ts +42 -0
- package/dist/privacy/key-distribution.d.ts.map +1 -0
- package/dist/privacy/key-distribution.js +50 -0
- package/dist/privacy/key-distribution.js.map +1 -0
- package/dist/privacy/privacy-guard.d.ts +24 -0
- package/dist/privacy/privacy-guard.d.ts.map +1 -0
- package/dist/privacy/privacy-guard.js +87 -0
- package/dist/privacy/privacy-guard.js.map +1 -0
- package/dist/privacy/space-encryption.d.ts +48 -0
- package/dist/privacy/space-encryption.d.ts.map +1 -0
- package/dist/privacy/space-encryption.js +61 -0
- package/dist/privacy/space-encryption.js.map +1 -0
- package/dist/query/engine.d.ts +27 -0
- package/dist/query/engine.d.ts.map +1 -0
- package/dist/query/engine.js +84 -0
- package/dist/query/engine.js.map +1 -0
- package/dist/query/filter.d.ts +15 -0
- package/dist/query/filter.d.ts.map +1 -0
- package/dist/query/filter.js +207 -0
- package/dist/query/filter.js.map +1 -0
- package/dist/query/types.d.ts +144 -0
- package/dist/query/types.d.ts.map +1 -0
- package/dist/query/types.js +22 -0
- package/dist/query/types.js.map +1 -0
- package/dist/react/context.d.ts +81 -0
- package/dist/react/context.d.ts.map +1 -0
- package/dist/react/context.js +95 -0
- package/dist/react/context.js.map +1 -0
- package/dist/react/index.d.ts +40 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +36 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/use-live.d.ts +16 -0
- package/dist/react/use-live.d.ts.map +1 -0
- package/dist/react/use-live.js +55 -0
- package/dist/react/use-live.js.map +1 -0
- package/dist/react/use-query.d.ts +17 -0
- package/dist/react/use-query.d.ts.map +1 -0
- package/dist/react/use-query.js +23 -0
- package/dist/react/use-query.js.map +1 -0
- package/dist/react/use-space.d.ts +29 -0
- package/dist/react/use-space.d.ts.map +1 -0
- package/dist/react/use-space.js +48 -0
- package/dist/react/use-space.js.map +1 -0
- package/dist/react/use-spaces.d.ts +19 -0
- package/dist/react/use-spaces.d.ts.map +1 -0
- package/dist/react/use-spaces.js +55 -0
- package/dist/react/use-spaces.js.map +1 -0
- package/dist/react/use-weave-auth.d.ts +10 -0
- package/dist/react/use-weave-auth.d.ts.map +1 -0
- package/dist/react/use-weave-auth.js +15 -0
- package/dist/react/use-weave-auth.js.map +1 -0
- package/dist/react/weave-auth.d.ts +17 -0
- package/dist/react/weave-auth.d.ts.map +1 -0
- package/dist/react/weave-auth.js +38 -0
- package/dist/react/weave-auth.js.map +1 -0
- package/dist/records/describe.d.ts +38 -0
- package/dist/records/describe.d.ts.map +1 -0
- package/dist/records/describe.js +101 -0
- package/dist/records/describe.js.map +1 -0
- package/dist/records/links.d.ts +14 -0
- package/dist/records/links.d.ts.map +1 -0
- package/dist/records/links.js +25 -0
- package/dist/records/links.js.map +1 -0
- package/dist/records/rules.d.ts +59 -0
- package/dist/records/rules.d.ts.map +1 -0
- package/dist/records/rules.js +118 -0
- package/dist/records/rules.js.map +1 -0
- package/dist/records/version.d.ts +54 -0
- package/dist/records/version.d.ts.map +1 -0
- package/dist/records/version.js +70 -0
- package/dist/records/version.js.map +1 -0
- package/dist/schema/collection-def.d.ts +96 -0
- package/dist/schema/collection-def.d.ts.map +1 -0
- package/dist/schema/collection-def.js +272 -0
- package/dist/schema/collection-def.js.map +1 -0
- package/dist/schema/expression.d.ts +69 -0
- package/dist/schema/expression.d.ts.map +1 -0
- package/dist/schema/expression.js +92 -0
- package/dist/schema/expression.js.map +1 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/schema-engine.d.ts +42 -0
- package/dist/schema/schema-engine.d.ts.map +1 -0
- package/dist/schema/schema-engine.js +36 -0
- package/dist/schema/schema-engine.js.map +1 -0
- package/dist/schema/signer.d.ts +27 -0
- package/dist/schema/signer.d.ts.map +1 -0
- package/dist/schema/signer.js +36 -0
- package/dist/schema/signer.js.map +1 -0
- package/dist/schemas/apps.d.ts +88 -0
- package/dist/schemas/apps.d.ts.map +1 -0
- package/dist/schemas/apps.js +168 -0
- package/dist/schemas/apps.js.map +1 -0
- package/dist/schemas/index.d.ts +410 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +208 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/screens.d.ts +67 -0
- package/dist/schemas/screens.d.ts.map +1 -0
- package/dist/schemas/screens.js +242 -0
- package/dist/schemas/screens.js.map +1 -0
- package/dist/session/agent-link.d.ts +79 -0
- package/dist/session/agent-link.d.ts.map +1 -0
- package/dist/session/agent-link.js +251 -0
- package/dist/session/agent-link.js.map +1 -0
- package/dist/session/auth.d.ts +233 -0
- package/dist/session/auth.d.ts.map +1 -0
- package/dist/session/auth.js +783 -0
- package/dist/session/auth.js.map +1 -0
- package/dist/session/connect.d.ts +211 -0
- package/dist/session/connect.d.ts.map +1 -0
- package/dist/session/connect.js +355 -0
- package/dist/session/connect.js.map +1 -0
- package/dist/session/connection.d.ts +70 -0
- package/dist/session/connection.d.ts.map +1 -0
- package/dist/session/connection.js +120 -0
- package/dist/session/connection.js.map +1 -0
- package/dist/session/credentials.d.ts +44 -0
- package/dist/session/credentials.d.ts.map +1 -0
- package/dist/session/credentials.js +60 -0
- package/dist/session/credentials.js.map +1 -0
- package/dist/session/index.d.ts +25 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +18 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/pairing.d.ts +59 -0
- package/dist/session/pairing.d.ts.map +1 -0
- package/dist/session/pairing.js +144 -0
- package/dist/session/pairing.js.map +1 -0
- package/dist/session/places.d.ts +62 -0
- package/dist/session/places.d.ts.map +1 -0
- package/dist/session/places.js +101 -0
- package/dist/session/places.js.map +1 -0
- package/dist/session/stay-signed-in.d.ts +37 -0
- package/dist/session/stay-signed-in.d.ts.map +1 -0
- package/dist/session/stay-signed-in.js +124 -0
- package/dist/session/stay-signed-in.js.map +1 -0
- package/dist/space/account-registry.d.ts +64 -0
- package/dist/space/account-registry.d.ts.map +1 -0
- package/dist/space/account-registry.js +66 -0
- package/dist/space/account-registry.js.map +1 -0
- package/dist/space/index.d.ts +3 -0
- package/dist/space/index.d.ts.map +1 -0
- package/dist/space/index.js +3 -0
- package/dist/space/index.js.map +1 -0
- package/dist/space/pass.d.ts +63 -0
- package/dist/space/pass.d.ts.map +1 -0
- package/dist/space/pass.js +54 -0
- package/dist/space/pass.js.map +1 -0
- package/dist/space/presets.d.ts +31 -0
- package/dist/space/presets.d.ts.map +1 -0
- package/dist/space/presets.js +24 -0
- package/dist/space/presets.js.map +1 -0
- package/dist/space/roles.d.ts +186 -0
- package/dist/space/roles.d.ts.map +1 -0
- package/dist/space/roles.js +500 -0
- package/dist/space/roles.js.map +1 -0
- package/dist/space/space-access.d.ts +80 -0
- package/dist/space/space-access.d.ts.map +1 -0
- package/dist/space/space-access.js +135 -0
- package/dist/space/space-access.js.map +1 -0
- package/dist/space/space-manager.d.ts +87 -0
- package/dist/space/space-manager.d.ts.map +1 -0
- package/dist/space/space-manager.js +187 -0
- package/dist/space/space-manager.js.map +1 -0
- package/dist/storage/directory-access.d.ts +78 -0
- package/dist/storage/directory-access.d.ts.map +1 -0
- package/dist/storage/directory-access.js +164 -0
- package/dist/storage/directory-access.js.map +1 -0
- package/dist/storage/encrypted-adapter.d.ts +49 -0
- package/dist/storage/encrypted-adapter.d.ts.map +1 -0
- package/dist/storage/encrypted-adapter.js +106 -0
- package/dist/storage/encrypted-adapter.js.map +1 -0
- package/dist/storage/folder-adapter.d.ts +105 -0
- package/dist/storage/folder-adapter.d.ts.map +1 -0
- package/dist/storage/folder-adapter.js +280 -0
- package/dist/storage/folder-adapter.js.map +1 -0
- package/dist/storage/folder-reconcile.d.ts +53 -0
- package/dist/storage/folder-reconcile.d.ts.map +1 -0
- package/dist/storage/folder-reconcile.js +65 -0
- package/dist/storage/folder-reconcile.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +9 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/indexeddb-adapter.d.ts +12 -0
- package/dist/storage/indexeddb-adapter.d.ts.map +1 -0
- package/dist/storage/indexeddb-adapter.js +190 -0
- package/dist/storage/indexeddb-adapter.js.map +1 -0
- package/dist/storage/mst.d.ts +121 -0
- package/dist/storage/mst.d.ts.map +1 -0
- package/dist/storage/mst.js +402 -0
- package/dist/storage/mst.js.map +1 -0
- package/dist/storage/storage-provider.d.ts +85 -0
- package/dist/storage/storage-provider.d.ts.map +1 -0
- package/dist/storage/storage-provider.js +220 -0
- package/dist/storage/storage-provider.js.map +1 -0
- package/dist/sync/anti-entropy.d.ts +49 -0
- package/dist/sync/anti-entropy.d.ts.map +1 -0
- package/dist/sync/anti-entropy.js +62 -0
- package/dist/sync/anti-entropy.js.map +1 -0
- package/dist/sync/index.d.ts +4 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +4 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/sync-engine.d.ts +71 -0
- package/dist/sync/sync-engine.d.ts.map +1 -0
- package/dist/sync/sync-engine.js +309 -0
- package/dist/sync/sync-engine.js.map +1 -0
- package/dist/sync/sync-messages.d.ts +75 -0
- package/dist/sync/sync-messages.d.ts.map +1 -0
- package/dist/sync/sync-messages.js +12 -0
- package/dist/sync/sync-messages.js.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/encoding.d.ts +63 -0
- package/dist/utils/encoding.d.ts.map +1 -0
- package/dist/utils/encoding.js +130 -0
- package/dist/utils/encoding.js.map +1 -0
- package/dist/utils/errors.d.ts +43 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +28 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/events.d.ts +19 -0
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/events.js +27 -0
- package/dist/utils/events.js.map +1 -0
- package/dist/utils/hash.d.ts +23 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +49 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/validation/capability-gate.d.ts +50 -0
- package/dist/validation/capability-gate.d.ts.map +1 -0
- package/dist/validation/capability-gate.js +71 -0
- package/dist/validation/capability-gate.js.map +1 -0
- package/dist/validation/crypto-gate.d.ts +16 -0
- package/dist/validation/crypto-gate.d.ts.map +1 -0
- package/dist/validation/crypto-gate.js +37 -0
- package/dist/validation/crypto-gate.js.map +1 -0
- package/dist/validation/index.d.ts +6 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +6 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/stateful-gate.d.ts +15 -0
- package/dist/validation/stateful-gate.d.ts.map +1 -0
- package/dist/validation/stateful-gate.js +50 -0
- package/dist/validation/stateful-gate.js.map +1 -0
- package/dist/validation/structural-gate.d.ts +18 -0
- package/dist/validation/structural-gate.d.ts.map +1 -0
- package/dist/validation/structural-gate.js +54 -0
- package/dist/validation/structural-gate.js.map +1 -0
- package/dist/validation/validation-engine.d.ts +28 -0
- package/dist/validation/validation-engine.d.ts.map +1 -0
- package/dist/validation/validation-engine.js +38 -0
- package/dist/validation/validation-engine.js.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { AccountStore, AccountSummary } from '../identity/account-store.js';
|
|
2
|
+
import { type StoreFactory } from '../node/stores.js';
|
|
3
|
+
import type { DirectoryHandleLike } from '../storage/folder-adapter.js';
|
|
4
|
+
/** Where accounts and their data are kept */
|
|
5
|
+
export interface Place {
|
|
6
|
+
readonly kind: 'folder' | 'browser';
|
|
7
|
+
readonly store: AccountStore;
|
|
8
|
+
/** The folder, when there is one — for its name, and for opening stores */
|
|
9
|
+
readonly directory: DirectoryHandleLike | null;
|
|
10
|
+
}
|
|
11
|
+
/** What a pod holds, for deciding what to do before switching to it */
|
|
12
|
+
export interface PodContents {
|
|
13
|
+
/** This account's copy in the pod, when it has one */
|
|
14
|
+
readonly account: AccountSummary | null;
|
|
15
|
+
/** Other accounts in the pod — never touched by a move */
|
|
16
|
+
readonly others: number;
|
|
17
|
+
/** It is the pod already in use */
|
|
18
|
+
readonly same: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Accounts kept in this browser. Always available; never shared with another site. */
|
|
21
|
+
export declare function browserPlace(): Promise<Place>;
|
|
22
|
+
/** Wraps a folder as a place. */
|
|
23
|
+
export declare function folderPlace(directory: DirectoryHandleLike): Place;
|
|
24
|
+
/**
|
|
25
|
+
* Asks for a pod without switching to it — so a signed-in person can be asked
|
|
26
|
+
* what should happen to their data first. Must be called from a click.
|
|
27
|
+
*/
|
|
28
|
+
export declare function pickPod(): Promise<Place>;
|
|
29
|
+
/** Remembers a pod as the one this site opens next time. */
|
|
30
|
+
export declare function rememberPod(pod: Place): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Re-opens the pod this site used last.
|
|
33
|
+
*
|
|
34
|
+
* @param request Whether to prompt for permission. Needs a click when true; use
|
|
35
|
+
* false on page load to find out whether a button has to be shown.
|
|
36
|
+
* @returns The pod, or null when there is none or access was declined
|
|
37
|
+
*/
|
|
38
|
+
export declare function recallPod(request: boolean): Promise<Place | null>;
|
|
39
|
+
/** Stops using the pod. Nothing in it is touched. */
|
|
40
|
+
export declare function forgetPod(): Promise<void>;
|
|
41
|
+
/** Every account in a place, most recently used first. */
|
|
42
|
+
export declare function listAccounts(place: Place): Promise<ReadonlyArray<AccountSummary>>;
|
|
43
|
+
/** What a pod holds of this account and others, and whether it is the one in use. */
|
|
44
|
+
export declare function inspectPod(pod: Place, current: Place, did: string): Promise<PodContents>;
|
|
45
|
+
/**
|
|
46
|
+
* The stores for one account.
|
|
47
|
+
*
|
|
48
|
+
* Paths are account-scoped either way, so two accounts in one browser never
|
|
49
|
+
* share a store, the same way two accounts in one folder never share a subtree.
|
|
50
|
+
* A pod's registry is sealed under the vault key, so someone who copies the
|
|
51
|
+
* folder cannot read the private spaces in it.
|
|
52
|
+
*
|
|
53
|
+
* @param account Whose data
|
|
54
|
+
* @param folder The unlocked pod and its vault key, when the account lives in one
|
|
55
|
+
*/
|
|
56
|
+
export declare function storesFor(account: AccountSummary, folder?: {
|
|
57
|
+
readonly directory: DirectoryHandleLike;
|
|
58
|
+
readonly vaultKey: CryptoKey;
|
|
59
|
+
}): StoreFactory;
|
|
60
|
+
/** Deletes the IndexedDB databases an account kept in this browser. */
|
|
61
|
+
export declare function deleteBrowserData(account: AccountSummary): Promise<void>;
|
|
62
|
+
//# sourceMappingURL=places.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"places.d.ts","sourceRoot":"","sources":["../../src/session/places.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAQjF,OAAO,EAAiC,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,6CAA6C;AAC7C,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAChD;AAED,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,uFAAuF;AACvF,wBAAsB,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,CAEnD;AAED,iCAAiC;AACjC,wBAAgB,WAAW,CAAC,SAAS,EAAE,mBAAmB,GAAG,KAAK,CAEjE;AAED;;;GAGG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,CAE9C;AAED,4DAA4D;AAC5D,wBAAsB,WAAW,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3D;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAKvE;AAED,qDAAqD;AACrD,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,0DAA0D;AAC1D,wBAAsB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAEvF;AAED,qFAAqF;AACrF,wBAAsB,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAc9F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,GACjF,YAAY,CAId;AAED,uEAAuE;AACvE,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAe9E"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module session/places
|
|
3
|
+
* Where accounts and their data are kept: a pod, or this browser.
|
|
4
|
+
*
|
|
5
|
+
* Two questions a sign-in flow keeps apart:
|
|
6
|
+
*
|
|
7
|
+
* - **Where does my data live?** A folder you picked (a *pod*), or this
|
|
8
|
+
* browser. That is a place.
|
|
9
|
+
* - **Who am I?** An account in that place. A place can hold several.
|
|
10
|
+
*/
|
|
11
|
+
import { createBrowserAccountStore, createFolderAccountStore, listFolderAccounts } from '../identity/account-store.js';
|
|
12
|
+
import { forgetDataFolder, ensureFolderPermission, pickDataFolder, recallDataFolder, rememberDataFolder, } from '../storage/directory-access.js';
|
|
13
|
+
import { folderStores, indexedDBStores } from '../node/stores.js';
|
|
14
|
+
/** Accounts kept in this browser. Always available; never shared with another site. */
|
|
15
|
+
export async function browserPlace() {
|
|
16
|
+
return { kind: 'browser', store: await createBrowserAccountStore(), directory: null };
|
|
17
|
+
}
|
|
18
|
+
/** Wraps a folder as a place. */
|
|
19
|
+
export function folderPlace(directory) {
|
|
20
|
+
return { kind: 'folder', store: createFolderAccountStore(directory), directory };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Asks for a pod without switching to it — so a signed-in person can be asked
|
|
24
|
+
* what should happen to their data first. Must be called from a click.
|
|
25
|
+
*/
|
|
26
|
+
export async function pickPod() {
|
|
27
|
+
return folderPlace(await pickDataFolder({ id: 'weave-pod' }));
|
|
28
|
+
}
|
|
29
|
+
/** Remembers a pod as the one this site opens next time. */
|
|
30
|
+
export async function rememberPod(pod) {
|
|
31
|
+
if (!pod.directory)
|
|
32
|
+
throw new Error('That is not a folder.');
|
|
33
|
+
await rememberDataFolder(pod.directory);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Re-opens the pod this site used last.
|
|
37
|
+
*
|
|
38
|
+
* @param request Whether to prompt for permission. Needs a click when true; use
|
|
39
|
+
* false on page load to find out whether a button has to be shown.
|
|
40
|
+
* @returns The pod, or null when there is none or access was declined
|
|
41
|
+
*/
|
|
42
|
+
export async function recallPod(request) {
|
|
43
|
+
const directory = await recallDataFolder();
|
|
44
|
+
if (!directory)
|
|
45
|
+
return null;
|
|
46
|
+
if (!(await ensureFolderPermission(directory, { request })))
|
|
47
|
+
return null;
|
|
48
|
+
return folderPlace(directory);
|
|
49
|
+
}
|
|
50
|
+
/** Stops using the pod. Nothing in it is touched. */
|
|
51
|
+
export async function forgetPod() {
|
|
52
|
+
await forgetDataFolder();
|
|
53
|
+
}
|
|
54
|
+
/** Every account in a place, most recently used first. */
|
|
55
|
+
export async function listAccounts(place) {
|
|
56
|
+
return place.directory ? listFolderAccounts(place.directory, place.store) : place.store.list();
|
|
57
|
+
}
|
|
58
|
+
/** What a pod holds of this account and others, and whether it is the one in use. */
|
|
59
|
+
export async function inspectPod(pod, current, did) {
|
|
60
|
+
const accounts = await listAccounts(pod);
|
|
61
|
+
const same = current.kind === 'folder' &&
|
|
62
|
+
!!current.directory &&
|
|
63
|
+
!!pod.directory &&
|
|
64
|
+
(await pod.directory
|
|
65
|
+
.isSameEntry?.(current.directory)
|
|
66
|
+
.catch(() => false)) === true;
|
|
67
|
+
return {
|
|
68
|
+
account: accounts.find((account) => account.did === did) ?? null,
|
|
69
|
+
others: accounts.filter((account) => account.did !== did).length,
|
|
70
|
+
same,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The stores for one account.
|
|
75
|
+
*
|
|
76
|
+
* Paths are account-scoped either way, so two accounts in one browser never
|
|
77
|
+
* share a store, the same way two accounts in one folder never share a subtree.
|
|
78
|
+
* A pod's registry is sealed under the vault key, so someone who copies the
|
|
79
|
+
* folder cannot read the private spaces in it.
|
|
80
|
+
*
|
|
81
|
+
* @param account Whose data
|
|
82
|
+
* @param folder The unlocked pod and its vault key, when the account lives in one
|
|
83
|
+
*/
|
|
84
|
+
export function storesFor(account, folder) {
|
|
85
|
+
return folder
|
|
86
|
+
? folderStores(folder.directory, { basePath: account.dataPath, vaultKey: folder.vaultKey })
|
|
87
|
+
: indexedDBStores(`weave:${account.dataPath.replace(/\//g, ':')}`);
|
|
88
|
+
}
|
|
89
|
+
/** Deletes the IndexedDB databases an account kept in this browser. */
|
|
90
|
+
export async function deleteBrowserData(account) {
|
|
91
|
+
const prefix = `weave:${account.dataPath.replace(/\//g, ':')}`;
|
|
92
|
+
const databases = (await globalThis.indexedDB.databases?.()) ?? [];
|
|
93
|
+
await Promise.all(databases
|
|
94
|
+
.map((db) => db.name)
|
|
95
|
+
.filter((name) => typeof name === 'string' && name.startsWith(prefix))
|
|
96
|
+
.map((name) => new Promise((resolve) => {
|
|
97
|
+
const request = globalThis.indexedDB.deleteDatabase(name);
|
|
98
|
+
request.onsuccess = request.onerror = request.onblocked = () => resolve();
|
|
99
|
+
})));
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=places.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"places.js","sourceRoot":"","sources":["../../src/session/places.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** How long an unused device stays signed in */
|
|
2
|
+
export type StaySignedIn = 'never' | '1d' | '7d' | '30d';
|
|
3
|
+
export declare const STAY_SIGNED_IN_CHOICES: ReadonlyArray<{
|
|
4
|
+
value: StaySignedIn;
|
|
5
|
+
label: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const DEFAULT_STAY_SIGNED_IN: StaySignedIn;
|
|
8
|
+
/** The little of `localStorage` this needs — swappable, for tests and for other hosts */
|
|
9
|
+
export interface KeyValueStore {
|
|
10
|
+
getItem(key: string): string | null;
|
|
11
|
+
setItem(key: string, value: string): void;
|
|
12
|
+
removeItem(key: string): void;
|
|
13
|
+
}
|
|
14
|
+
export interface StaySignedInStore {
|
|
15
|
+
/** The chosen length */
|
|
16
|
+
choice(): StaySignedIn;
|
|
17
|
+
/** Changes it. "Ask every time" forgets the current one straight away; a new length applies from now. */
|
|
18
|
+
setChoice(choice: StaySignedIn): Promise<void>;
|
|
19
|
+
/** Keeps the seed on this device after an unlock, when the choice allows it */
|
|
20
|
+
remember(accountId: string, place: 'browser' | 'folder', seed: Uint8Array): Promise<void>;
|
|
21
|
+
/** The seed this device kept, if still in date and for the kind of place that is open. Using it pushes the expiry forward. */
|
|
22
|
+
recall(place: 'browser' | 'folder'): Promise<{
|
|
23
|
+
accountId: string;
|
|
24
|
+
seed: Uint8Array;
|
|
25
|
+
} | null>;
|
|
26
|
+
/** When the kept sign-in runs out, or null when there is none */
|
|
27
|
+
until(): Date | null;
|
|
28
|
+
/** Deletes the kept key: the next visit asks to unlock */
|
|
29
|
+
forget(): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* @param storage Where the setting and the wrapped seed are kept
|
|
33
|
+
* @param rpId The site the device key belongs to
|
|
34
|
+
* @param prefix Namespaces the keys, so two apps on one origin do not share a sign-in
|
|
35
|
+
*/
|
|
36
|
+
export declare function createStaySignedIn(storage: KeyValueStore | null, rpId: string, prefix?: string): StaySignedInStore;
|
|
37
|
+
//# sourceMappingURL=stay-signed-in.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stay-signed-in.d.ts","sourceRoot":"","sources":["../../src/session/stay-signed-in.ts"],"names":[],"mappings":"AAwBA,gDAAgD;AAChD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;AAEzD,eAAO,MAAM,sBAAsB,EAAE,aAAa,CAAC;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAKxF,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,YAAmB,CAAC;AAKzD,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAWD,MAAM,WAAW,iBAAiB;IAChC,wBAAwB;IACxB,MAAM,IAAI,YAAY,CAAC;IACvB,yGAAyG;IACzG,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,8HAA8H;IAC9H,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC7F,iEAAiE;IACjE,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC;IACrB,0DAA0D;IAC1D,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAU,GAAG,iBAAiB,CAiFnH"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module session/stay-signed-in
|
|
3
|
+
* Staying signed in on this device, so a refresh does not ask to unlock again.
|
|
4
|
+
*
|
|
5
|
+
* The seed is encrypted under a device key: a random key the browser keeps in
|
|
6
|
+
* this site's storage and will use for this page but never hand out as bytes
|
|
7
|
+
* (it is created non-extractable). The same thing a passkey shortcut does,
|
|
8
|
+
* minus the fingerprint — which is exactly the convenience asked for, and
|
|
9
|
+
* exactly the cost:
|
|
10
|
+
*
|
|
11
|
+
* - Someone who copies this site's stored data somewhere else gets ciphertext
|
|
12
|
+
* and no key to open it.
|
|
13
|
+
* - Someone at this computer, in this browser profile, is signed in. So is any
|
|
14
|
+
* script running in this page. That is what "stay signed in" means anywhere.
|
|
15
|
+
*
|
|
16
|
+
* So it expires: after a chosen time without being used, the key is deleted
|
|
17
|
+
* and the next visit asks to unlock. Signing out deletes it at once.
|
|
18
|
+
*
|
|
19
|
+
* Kept in this browser only, never in a pod — a pod is meant to be copied and
|
|
20
|
+
* synced, and "this device may skip the password" must not travel with it.
|
|
21
|
+
*/
|
|
22
|
+
import { createDeviceKey, deleteDeviceKey, getDeviceKey } from '../identity/device-key.js';
|
|
23
|
+
import { unwrapSeedWithDeviceKey, wrapSeedWithDeviceKey } from '../identity/account-vault.js';
|
|
24
|
+
export const STAY_SIGNED_IN_CHOICES = [
|
|
25
|
+
{ value: 'never', label: 'Ask every time' },
|
|
26
|
+
{ value: '1d', label: '1 day' },
|
|
27
|
+
{ value: '7d', label: '7 days' },
|
|
28
|
+
{ value: '30d', label: '30 days' },
|
|
29
|
+
];
|
|
30
|
+
export const DEFAULT_STAY_SIGNED_IN = '7d';
|
|
31
|
+
const DAY = 24 * 60 * 60 * 1000;
|
|
32
|
+
const DURATION = { never: 0, '1d': DAY, '7d': 7 * DAY, '30d': 30 * DAY };
|
|
33
|
+
/**
|
|
34
|
+
* @param storage Where the setting and the wrapped seed are kept
|
|
35
|
+
* @param rpId The site the device key belongs to
|
|
36
|
+
* @param prefix Namespaces the keys, so two apps on one origin do not share a sign-in
|
|
37
|
+
*/
|
|
38
|
+
export function createStaySignedIn(storage, rpId, prefix = 'weave') {
|
|
39
|
+
const SETTING = `${prefix}.stay-signed-in`;
|
|
40
|
+
const RECORD = `${prefix}.remembered-session`;
|
|
41
|
+
const read = (key) => {
|
|
42
|
+
try {
|
|
43
|
+
const raw = storage?.getItem(key);
|
|
44
|
+
return raw ? JSON.parse(raw) : null;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const write = (key, value) => {
|
|
51
|
+
try {
|
|
52
|
+
if (value === null)
|
|
53
|
+
storage?.removeItem(key);
|
|
54
|
+
else
|
|
55
|
+
storage?.setItem(key, JSON.stringify(value));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* private mode: it will ask again next time, which is safe */
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const choice = () => {
|
|
62
|
+
const chosen = read(SETTING);
|
|
63
|
+
return chosen && chosen in DURATION ? chosen : DEFAULT_STAY_SIGNED_IN;
|
|
64
|
+
};
|
|
65
|
+
const forget = async () => {
|
|
66
|
+
const current = read(RECORD);
|
|
67
|
+
write(RECORD, null);
|
|
68
|
+
if (current)
|
|
69
|
+
await deleteDeviceKey(current.wrap.deviceKeyId).catch(() => { });
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
choice,
|
|
73
|
+
forget,
|
|
74
|
+
async setChoice(next) {
|
|
75
|
+
write(SETTING, next);
|
|
76
|
+
const current = read(RECORD);
|
|
77
|
+
if (!current)
|
|
78
|
+
return;
|
|
79
|
+
if (next === 'never')
|
|
80
|
+
await forget();
|
|
81
|
+
else
|
|
82
|
+
write(RECORD, { ...current, expiresAt: Date.now() + DURATION[next] });
|
|
83
|
+
},
|
|
84
|
+
async remember(accountId, place, seed) {
|
|
85
|
+
await forget();
|
|
86
|
+
const chosen = choice();
|
|
87
|
+
if (chosen === 'never')
|
|
88
|
+
return;
|
|
89
|
+
const deviceKey = await createDeviceKey();
|
|
90
|
+
const wrap = await wrapSeedWithDeviceKey(seed, deviceKey, { rpId, label: 'stay signed in' });
|
|
91
|
+
write(RECORD, { accountId, place, wrap, expiresAt: Date.now() + DURATION[chosen] });
|
|
92
|
+
},
|
|
93
|
+
async recall(place) {
|
|
94
|
+
const current = read(RECORD);
|
|
95
|
+
if (!current)
|
|
96
|
+
return null;
|
|
97
|
+
if (current.expiresAt < Date.now()) {
|
|
98
|
+
await forget();
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
if (current.place !== place)
|
|
102
|
+
return null;
|
|
103
|
+
const key = await getDeviceKey(current.wrap.deviceKeyId);
|
|
104
|
+
if (!key) {
|
|
105
|
+
write(RECORD, null);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const seed = await unwrapSeedWithDeviceKey(current.wrap, key);
|
|
110
|
+
write(RECORD, { ...current, expiresAt: Date.now() + DURATION[choice()] });
|
|
111
|
+
return { accountId: current.accountId, seed };
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
await forget();
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
until() {
|
|
119
|
+
const current = read(RECORD);
|
|
120
|
+
return current && current.expiresAt > Date.now() ? new Date(current.expiresAt) : null;
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=stay-signed-in.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stay-signed-in.js","sourceRoot":"","sources":["../../src/session/stay-signed-in.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module account-registry
|
|
3
|
+
* The account's own list of spaces, kept in a space.
|
|
4
|
+
*
|
|
5
|
+
* Without it, which spaces an account belongs to lives on each device alone: a
|
|
6
|
+
* new phone, a new app or an always-on node has to be handed every invite. With
|
|
7
|
+
* it, joining a space on one device writes a membership record into a private
|
|
8
|
+
* space only the account can find, and every other device and node of the
|
|
9
|
+
* account syncs that record and joins by itself.
|
|
10
|
+
*
|
|
11
|
+
* The registry's key and nonce are derived from the account's vault key, and
|
|
12
|
+
* its id is the hash of its genesis like any space's — so nothing needs to be
|
|
13
|
+
* exchanged to find it, and nobody without the account can. The DID alone is
|
|
14
|
+
* not enough: it appears in everything the account signs, and a room named
|
|
15
|
+
* after it could be found by anyone who had seen its data.
|
|
16
|
+
*/
|
|
17
|
+
import type { CryptoProvider } from '../types.js';
|
|
18
|
+
import type { SpaceRecord } from './space-manager.js';
|
|
19
|
+
/**
|
|
20
|
+
* Where the account's list of spaces lives, one record per space it follows.
|
|
21
|
+
* Not to be confused with `sys.member`, a space's own record of who holds
|
|
22
|
+
* which role there.
|
|
23
|
+
*/
|
|
24
|
+
export declare const MEMBERSHIP_COLLECTION = "sys.joined";
|
|
25
|
+
/**
|
|
26
|
+
* The account's profile — what it is called — so a rename on one device or app
|
|
27
|
+
* reaches the others. The newest record wins.
|
|
28
|
+
*/
|
|
29
|
+
export declare const PROFILE_COLLECTION = "sys.profile";
|
|
30
|
+
/** The profile's record key — there is one profile per account */
|
|
31
|
+
export declare const PROFILE_KEY = "profile";
|
|
32
|
+
export interface AccountProfile {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
}
|
|
35
|
+
/** A membership record's body. The invite carries a private space's key — the registry is encrypted. */
|
|
36
|
+
export interface Membership {
|
|
37
|
+
readonly space: string;
|
|
38
|
+
readonly invite: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Carriers the account uses — a browser extension keeping its spaces online,
|
|
42
|
+
* say — one record each, key `carrier:<carry space id hash>`. Every device of
|
|
43
|
+
* the account reads them and keeps each carrier's passes current (`space/pass.ts`).
|
|
44
|
+
*/
|
|
45
|
+
export declare const CARRIER_COLLECTION = "sys.carrier";
|
|
46
|
+
/** A carrier record's body */
|
|
47
|
+
export interface Carrier {
|
|
48
|
+
/** The carry space shared with it */
|
|
49
|
+
readonly space: string;
|
|
50
|
+
/** A view-only invite to the carry space — how other devices of the account open it */
|
|
51
|
+
readonly invite: string;
|
|
52
|
+
/** The carrier's own key, as it appears to peers */
|
|
53
|
+
readonly did: string;
|
|
54
|
+
/** What it called itself */
|
|
55
|
+
readonly name: string;
|
|
56
|
+
readonly since: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The account's registry space, derived — the same on every device.
|
|
60
|
+
* @param accountKey The account's vault key bytes (`deriveVaultKeyBytes(seed)`)
|
|
61
|
+
* @param owner The account's DID
|
|
62
|
+
*/
|
|
63
|
+
export declare function deriveAccountRegistry(accountKey: Uint8Array, owner: string, provider?: CryptoProvider): Promise<SpaceRecord>;
|
|
64
|
+
//# sourceMappingURL=account-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-registry.d.ts","sourceRoot":"","sources":["../../src/space/account-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQtD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAEhD,kEAAkE;AAClE,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wGAAwG;AACxG,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAEhD,8BAA8B;AAC9B,MAAM,WAAW,OAAO;IACtB,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uFAAuF;IACvF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAYD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,cAAqC,GAC9C,OAAO,CAAC,WAAW,CAAC,CA8BtB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { base64UrlEncode, utf8Encode } from '../utils/encoding.js';
|
|
2
|
+
import { sha256 } from '../utils/hash.js';
|
|
3
|
+
import { createP256Provider } from '../identity/crypto-p256.js';
|
|
4
|
+
import { deriveReadKey, spaceGenesis, spaceIdOf } from './space-access.js';
|
|
5
|
+
import { solo } from './presets.js';
|
|
6
|
+
/**
|
|
7
|
+
* Where the account's list of spaces lives, one record per space it follows.
|
|
8
|
+
* Not to be confused with `sys.member`, a space's own record of who holds
|
|
9
|
+
* which role there.
|
|
10
|
+
*/
|
|
11
|
+
export const MEMBERSHIP_COLLECTION = 'sys.joined';
|
|
12
|
+
/**
|
|
13
|
+
* The account's profile — what it is called — so a rename on one device or app
|
|
14
|
+
* reaches the others. The newest record wins.
|
|
15
|
+
*/
|
|
16
|
+
export const PROFILE_COLLECTION = 'sys.profile';
|
|
17
|
+
/** The profile's record key — there is one profile per account */
|
|
18
|
+
export const PROFILE_KEY = 'profile';
|
|
19
|
+
/**
|
|
20
|
+
* Carriers the account uses — a browser extension keeping its spaces online,
|
|
21
|
+
* say — one record each, key `carrier:<carry space id hash>`. Every device of
|
|
22
|
+
* the account reads them and keeps each carrier's passes current (`space/pass.ts`).
|
|
23
|
+
*/
|
|
24
|
+
export const CARRIER_COLLECTION = 'sys.carrier';
|
|
25
|
+
async function expand(accountKey, info) {
|
|
26
|
+
const material = await globalThis.crypto.subtle.importKey('raw', accountKey, 'HKDF', false, ['deriveBits']);
|
|
27
|
+
const bits = await globalThis.crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(0), info: utf8Encode(info) }, material, 256);
|
|
28
|
+
return new Uint8Array(bits);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The account's registry space, derived — the same on every device.
|
|
32
|
+
* @param accountKey The account's vault key bytes (`deriveVaultKeyBytes(seed)`)
|
|
33
|
+
* @param owner The account's DID
|
|
34
|
+
*/
|
|
35
|
+
export async function deriveAccountRegistry(accountKey, owner, provider = createP256Provider()) {
|
|
36
|
+
const nonce = base64UrlEncode((await expand(accountKey, 'weave/account-registry/nonce/v1')).subarray(0, 12));
|
|
37
|
+
const keyBytes = await expand(accountKey, 'weave/account-registry/key/v1');
|
|
38
|
+
const cryptoKey = await globalThis.crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM', length: 256 }, true, [
|
|
39
|
+
'encrypt',
|
|
40
|
+
'decrypt',
|
|
41
|
+
]);
|
|
42
|
+
const createdAt = new Date(0).toISOString(); // fixed, so every device derives the same record
|
|
43
|
+
const key = Object.freeze({
|
|
44
|
+
id: base64UrlEncode(await sha256(keyBytes)),
|
|
45
|
+
key: cryptoKey,
|
|
46
|
+
createdAt,
|
|
47
|
+
version: 1,
|
|
48
|
+
});
|
|
49
|
+
const fixed = {
|
|
50
|
+
visibility: 'private',
|
|
51
|
+
creator: owner,
|
|
52
|
+
roles: solo.roles,
|
|
53
|
+
creatorRole: solo.creatorRole,
|
|
54
|
+
createdAt,
|
|
55
|
+
nonce,
|
|
56
|
+
readKey: (await deriveReadKey(key, provider)).did,
|
|
57
|
+
encryptionKeyId: key.id,
|
|
58
|
+
};
|
|
59
|
+
const space = Object.freeze({
|
|
60
|
+
id: await spaceIdOf(spaceGenesis(fixed)),
|
|
61
|
+
...fixed,
|
|
62
|
+
name: 'Account registry',
|
|
63
|
+
});
|
|
64
|
+
return { space, key, invite: null, role: solo.creatorRole };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=account-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-registry.js","sourceRoot":"","sources":["../../src/space/account-registry.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAElD;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAEhD,kEAAkE;AAClE,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAYrC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAehD,KAAK,UAAU,MAAM,CAAC,UAAsB,EAAE,IAAY;IACxD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAA0B,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAC5H,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CACpD,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAiB,EAAE,EAClG,QAAQ,EACR,GAAG,CACJ,CAAC;IACF,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAsB,EACtB,KAAa,EACb,WAA2B,kBAAkB,EAAE;IAE/C,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,MAAM,MAAM,CAAC,UAAU,EAAE,iCAAiC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7G,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,+BAA+B,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,QAAwB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE;QAClI,SAAS;QACT,SAAS;KACV,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,iDAAiD;IAC9F,MAAM,GAAG,GAAa,MAAM,CAAC,MAAM,CAAC;QAClC,EAAE,EAAE,eAAe,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3C,GAAG,EAAE,SAAS;QACd,SAAS;QACT,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;IACH,MAAM,KAAK,GAAG;QACZ,UAAU,EAAE,SAAkB;QAC9B,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS;QACT,KAAK;QACL,OAAO,EAAE,CAAC,MAAM,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG;QACjD,eAAe,EAAE,GAAG,CAAC,EAAE;KACxB,CAAC;IACF,MAAM,KAAK,GAAU,MAAM,CAAC,MAAM,CAAC;QACjC,EAAE,EAAE,MAAM,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACxC,GAAG,KAAK;QACR,IAAI,EAAE,kBAAkB;KACzB,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/space/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/space/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module space/pass
|
|
3
|
+
* What a node needs to carry a space it cannot read.
|
|
4
|
+
*
|
|
5
|
+
* A carrier — a browser extension keeping your spaces online, later a host —
|
|
6
|
+
* stores a space's records, checks them the way every peer does, and passes
|
|
7
|
+
* them on. For that it needs two things, and must get nothing more:
|
|
8
|
+
*
|
|
9
|
+
* - **the space itself** (its genesis), which hashes to its id, so the carrier
|
|
10
|
+
* runs the same gates as any member;
|
|
11
|
+
* - **in a private space, the read key pair's seed**, because every peer must
|
|
12
|
+
* prove it may read before anything moves (`network/peer-auth.ts`). The read
|
|
13
|
+
* key only signs that proof. It is derived one way from the space key and
|
|
14
|
+
* decrypts nothing.
|
|
15
|
+
*
|
|
16
|
+
* No space key, no write secret, no note. A stolen pass lets someone download
|
|
17
|
+
* the space's encrypted records and their outer details — author, collection,
|
|
18
|
+
* times — which is what a blind host or a mirror's provider sees anyway.
|
|
19
|
+
*
|
|
20
|
+
* Passes travel in a **carry space**: a private space the account shares with
|
|
21
|
+
* one carrier, holding one pass record per space it should carry. Every node
|
|
22
|
+
* holding the account key keeps those records in step with the account's
|
|
23
|
+
* spaces (`node.ts`), so a space made in an app is carried without the home
|
|
24
|
+
* being opened.
|
|
25
|
+
*/
|
|
26
|
+
import type { CryptoProvider, Space } from '../types.js';
|
|
27
|
+
import type { SpaceRecord } from './space-manager.js';
|
|
28
|
+
import { type SpaceKeyPair } from './space-access.js';
|
|
29
|
+
/** Where passes live in a carry space */
|
|
30
|
+
export declare const PASS_COLLECTION = "sys.pass";
|
|
31
|
+
/**
|
|
32
|
+
* Written into a carry space when the account stops using the carrier. A
|
|
33
|
+
* carrier that reads it forgets everything it held.
|
|
34
|
+
*/
|
|
35
|
+
export declare const CARRY_CLOSED_KEY = "carry:closed";
|
|
36
|
+
/** A pass, as stored */
|
|
37
|
+
export interface SpacePass {
|
|
38
|
+
readonly v: 1;
|
|
39
|
+
readonly space: Space;
|
|
40
|
+
/** A private space's read key seed, base64url. Absent for a public space. */
|
|
41
|
+
readonly read?: string;
|
|
42
|
+
}
|
|
43
|
+
/** A pass, checked and ready to open a space with */
|
|
44
|
+
export interface OpenedPass {
|
|
45
|
+
readonly space: Space;
|
|
46
|
+
readonly read: SpaceKeyPair | null;
|
|
47
|
+
}
|
|
48
|
+
/** The record key of a space's pass */
|
|
49
|
+
export declare function passKey(spaceId: string): Promise<string>;
|
|
50
|
+
/**
|
|
51
|
+
* A pass for a space this node holds with its key.
|
|
52
|
+
* @throws For a private space held without its key: there is nothing to pass on
|
|
53
|
+
*/
|
|
54
|
+
export declare function makePass(record: SpaceRecord): Promise<SpacePass>;
|
|
55
|
+
/**
|
|
56
|
+
* Checks a pass someone handed over: the space must hash to its id, and the
|
|
57
|
+
* read key must be the one the space names.
|
|
58
|
+
* @returns The space and its read key pair, or null when the pass does not check out
|
|
59
|
+
*/
|
|
60
|
+
export declare function openPass(value: unknown, provider: CryptoProvider): Promise<OpenedPass | null>;
|
|
61
|
+
/** A record for opening a space from a pass: no key, no invite, no role */
|
|
62
|
+
export declare function carriedRecord(pass: OpenedPass): SpaceRecord;
|
|
63
|
+
//# sourceMappingURL=pass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pass.d.ts","sourceRoot":"","sources":["../../src/space/pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAA+C,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAInG,yCAAyC;AACzC,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,wBAAwB;AACxB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACd,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CACpC;AAED,uCAAuC;AACvC,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9D;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAItE;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAYnG;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAE3D"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { checkSpace, deriveReadSeed, readKeyFromSeed } from './space-access.js';
|
|
2
|
+
import { base64UrlDecode, base64UrlEncode, utf8Encode } from '../utils/encoding.js';
|
|
3
|
+
import { sha256 } from '../utils/hash.js';
|
|
4
|
+
/** Where passes live in a carry space */
|
|
5
|
+
export const PASS_COLLECTION = 'sys.pass';
|
|
6
|
+
/**
|
|
7
|
+
* Written into a carry space when the account stops using the carrier. A
|
|
8
|
+
* carrier that reads it forgets everything it held.
|
|
9
|
+
*/
|
|
10
|
+
export const CARRY_CLOSED_KEY = 'carry:closed';
|
|
11
|
+
/** The record key of a space's pass */
|
|
12
|
+
export async function passKey(spaceId) {
|
|
13
|
+
const digest = await sha256(utf8Encode(spaceId));
|
|
14
|
+
return `pass:${Array.from(digest.subarray(0, 20), (b) => b.toString(16).padStart(2, '0')).join('')}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A pass for a space this node holds with its key.
|
|
18
|
+
* @throws For a private space held without its key: there is nothing to pass on
|
|
19
|
+
*/
|
|
20
|
+
export async function makePass(record) {
|
|
21
|
+
if (record.space.visibility === 'public')
|
|
22
|
+
return { v: 1, space: record.space };
|
|
23
|
+
if (!record.key)
|
|
24
|
+
throw new Error(`"${record.space.name}" is held here without its key, so it cannot be passed on`);
|
|
25
|
+
return { v: 1, space: record.space, read: base64UrlEncode(await deriveReadSeed(record.key)) };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Checks a pass someone handed over: the space must hash to its id, and the
|
|
29
|
+
* read key must be the one the space names.
|
|
30
|
+
* @returns The space and its read key pair, or null when the pass does not check out
|
|
31
|
+
*/
|
|
32
|
+
export async function openPass(value, provider) {
|
|
33
|
+
const pass = value;
|
|
34
|
+
if (!pass || pass.v !== 1 || !pass.space)
|
|
35
|
+
return null;
|
|
36
|
+
if ((await checkSpace(pass.space)) !== null)
|
|
37
|
+
return null;
|
|
38
|
+
if (pass.space.visibility === 'public')
|
|
39
|
+
return { space: pass.space, read: null };
|
|
40
|
+
if (typeof pass.read !== 'string')
|
|
41
|
+
return null;
|
|
42
|
+
try {
|
|
43
|
+
const read = await readKeyFromSeed(base64UrlDecode(pass.read), provider);
|
|
44
|
+
return read.did === pass.space.readKey ? { space: pass.space, read } : null;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** A record for opening a space from a pass: no key, no invite, no role */
|
|
51
|
+
export function carriedRecord(pass) {
|
|
52
|
+
return { space: pass.space, key: null, invite: null, role: null, read: pass.read };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pass.js","sourceRoot":"","sources":["../../src/space/pass.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAqB,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,yCAAyC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAgB/C,uCAAuC;AACvC,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAe;IAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,OAAO,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AACvG,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAmB;IAChD,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAC/E,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,2DAA2D,CAAC,CAAC;IACnH,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,eAAe,CAAC,MAAM,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;AAChG,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAc,EAAE,QAAwB;IACrE,MAAM,IAAI,GAAG,KAAkC,CAAC;IAChD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,QAAQ;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjF,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,aAAa,CAAC,IAAgB;IAC5C,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;AACrF,CAAC"}
|