@dxos/credentials 2.33.0 → 2.33.1-dev.0a5ae2e2

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.
@@ -49,5 +49,5 @@ export interface TYPES {
49
49
  }
50
50
  export interface SERVICES {
51
51
  }
52
- export const schemaJson = JSON.parse("{\"nested\":{\"dxos\":{\"nested\":{\"credentials\":{\"nested\":{\"auth\":{\"nested\":{\"Auth\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"deviceKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null},\"identityKey\":{\"type\":\"PubKey\",\"id\":3,\"comment\":null},\"feedKey\":{\"type\":\"PubKey\",\"id\":4,\"comment\":null}},\"comment\":\"The payload for a SignedMessage sent during handshake for replication authentication.\"}}},\"greet\":{\"nested\":{\"BeginResponse\":{\"fields\":{\"info\":{\"keyType\":\"string\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"ClaimResponse\":{\"fields\":{\"id\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"rendezvousKey\":{\"type\":\"bytes\",\"id\":2,\"comment\":null}},\"comment\":null},\"Command\":{\"fields\":{\"command\":{\"type\":\"Type\",\"id\":1,\"comment\":null},\"secret\":{\"type\":\"bytes\",\"id\":2,\"comment\":null},\"params\":{\"rule\":\"repeated\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":null}},\"nested\":{\"Type\":{\"values\":{\"BEGIN\":0,\"HANDSHAKE\":1,\"NOTARIZE\":2,\"FINISH\":3,\"CLAIM\":10},\"comment\":null,\"comments\":{\"BEGIN\":null,\"HANDSHAKE\":null,\"NOTARIZE\":null,\"FINISH\":null,\"CLAIM\":null}}},\"comment\":\"A Greeter command.\"},\"HandshakeResponse\":{\"fields\":{\"nonce\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"partyKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null}},\"comment\":null},\"KeyHint\":{\"fields\":{\"publicKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"type\":{\"type\":\"KeyType\",\"id\":2,\"comment\":null}},\"comment\":null},\"NotarizeResponse\":{\"fields\":{\"copies\":{\"rule\":\"repeated\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null},\"hints\":{\"rule\":\"repeated\",\"type\":\"KeyHint\",\"id\":2,\"comment\":null}},\"comment\":null}}},\"identity\":{\"nested\":{\"DeviceInfo\":{\"fields\":{\"publicKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"displayName\":{\"type\":\"string\",\"id\":2,\"comment\":null}},\"comment\":null},\"IdentityInfo\":{\"fields\":{\"publicKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"displayName\":{\"type\":\"string\",\"id\":2,\"comment\":null}},\"comment\":null}}},\"Message\":{\"fields\":{\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"party\":{\"nested\":{\"Envelope\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"type\":\"Message\",\"id\":2,\"comment\":null}},\"comment\":null},\"FeedAdmit\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"feedKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null}},\"comment\":null},\"FeedGenesis\":{\"fields\":{\"feedKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"ownerKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null}},\"comment\":null},\"KeyAdmit\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"admitKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null},\"admitKeyType\":{\"type\":\"KeyType\",\"id\":3,\"comment\":null}},\"comment\":null},\"PartyCredential\":{\"oneofs\":{\"contents\":{\"oneof\":[\"envelope\",\"partyGenesis\",\"keyAdmit\",\"feedAdmit\",\"feedGenesis\"],\"comment\":null}},\"fields\":{\"type\":{\"type\":\"Type\",\"id\":1,\"comment\":null},\"envelope\":{\"type\":\"Envelope\",\"id\":10,\"comment\":null},\"partyGenesis\":{\"type\":\"PartyGenesis\",\"id\":11,\"comment\":null},\"keyAdmit\":{\"type\":\"KeyAdmit\",\"id\":12,\"comment\":null},\"feedAdmit\":{\"type\":\"FeedAdmit\",\"id\":13,\"comment\":null},\"feedGenesis\":{\"type\":\"FeedGenesis\",\"id\":14,\"comment\":null}},\"nested\":{\"Type\":{\"values\":{\"ENVELOPE\":0,\"PARTY_GENESIS\":1,\"FEED_GENESIS\":2,\"KEY_ADMIT\":3,\"FEED_ADMIT\":4},\"comment\":null,\"comments\":{\"ENVELOPE\":null,\"PARTY_GENESIS\":null,\"FEED_GENESIS\":null,\"KEY_ADMIT\":null,\"FEED_ADMIT\":null}}},\"comment\":null},\"PartyGenesis\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"feedKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null},\"admitKey\":{\"type\":\"PubKey\",\"id\":3,\"comment\":null},\"admitKeyType\":{\"type\":\"KeyType\",\"id\":4,\"comment\":null}},\"comment\":null},\"PartyInvitation\":{\"fields\":{\"id\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"partyKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null},\"issuerKey\":{\"type\":\"PubKey\",\"id\":3,\"comment\":null},\"inviteeKey\":{\"type\":\"PubKey\",\"id\":4,\"comment\":null}},\"comment\":null}}},\"SignedMessage\":{\"fields\":{\"signed\":{\"rule\":\"required\",\"type\":\"Signed\",\"id\":1,\"comment\":null},\"signatures\":{\"rule\":\"repeated\",\"type\":\"Signature\",\"id\":2,\"comment\":null}},\"nested\":{\"Signature\":{\"fields\":{\"key\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"signature\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"keyChain\":{\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"Signed\":{\"fields\":{\"created\":{\"rule\":\"required\",\"type\":\"string\",\"id\":1,\"comment\":null},\"nonce\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":null}},\"comment\":null}},\"comment\":\"A generic container message used whenever messages are signed (e.g. PartyCredential)\"}}},\"halo\":{\"nested\":{\"keys\":{\"nested\":{\"KeyChain\":{\"fields\":{\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"rule\":\"required\",\"type\":\"SignedMessage\",\"id\":2,\"comment\":null},\"parents\":{\"rule\":\"repeated\",\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"KeyRecord\":{\"fields\":{\"type\":{\"rule\":\"required\",\"type\":\"KeyType\",\"id\":1,\"comment\":\"- The `KeyType` type of the key. This is often unknown for keys from other sources.\"},\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":2,\"comment\":\"- The public key as a Buffer (required).\"},\"secretKey\":{\"type\":\"PrivKey\",\"id\":3,\"comment\":\"- The secret key as a Buffer (this will never be visible outside the Keyring).\"},\"hint\":{\"type\":\"bool\",\"id\":4,\"comment\":\"- Is this key from a Greeting \\\"hint\\\"?\"},\"own\":{\"type\":\"bool\",\"id\":5,\"comment\":\"- Is this our key? Usually true if `secretKey` is present,\\nmay be false for \\\"inception keys\\\" such as the Party key.\"},\"trusted\":{\"type\":\"bool\",\"id\":6,\"comment\":\"- Is this key to be trusted?\"},\"added\":{\"type\":\"string\",\"id\":7,\"comment\":\"- An RFC-3339 date/time string for when the key was added to the Keyring.\"},\"created\":{\"type\":\"string\",\"id\":8,\"comment\":\"- An RFC-3339 date/time string for when the key was created.\"}},\"comment\":null},\"KeyRecordList\":{\"fields\":{\"keys\":{\"rule\":\"repeated\",\"type\":\"KeyRecord\",\"id\":1,\"comment\":null}},\"comment\":null},\"KeyType\":{\"values\":{\"UNKNOWN\":0,\"IDENTITY\":1,\"DEVICE\":2,\"PARTY\":3,\"FEED\":4,\"DXNS_ADDRESS\":5},\"comment\":null,\"comments\":{\"UNKNOWN\":null,\"IDENTITY\":null,\"DEVICE\":null,\"PARTY\":null,\"FEED\":null,\"DXNS_ADDRESS\":null}},\"PrivKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"PubKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}}}}}}},\"google\":{\"nested\":{\"protobuf\":{\"nested\":{\"Any\":{\"fields\":{\"type_url\":{\"type\":\"string\",\"id\":1},\"value\":{\"type\":\"bytes\",\"id\":2}},\"comment\":null},\"BoolValue\":{\"fields\":{\"value\":{\"type\":\"bool\",\"id\":1}},\"comment\":null},\"BytesValue\":{\"fields\":{\"value\":{\"type\":\"bytes\",\"id\":1}},\"comment\":null},\"DoubleValue\":{\"fields\":{\"value\":{\"type\":\"double\",\"id\":1}},\"comment\":null},\"FloatValue\":{\"fields\":{\"value\":{\"type\":\"float\",\"id\":1}},\"comment\":null},\"Int32Value\":{\"fields\":{\"value\":{\"type\":\"int32\",\"id\":1}},\"comment\":null},\"Int64Value\":{\"fields\":{\"value\":{\"type\":\"int64\",\"id\":1}},\"comment\":null},\"StringValue\":{\"fields\":{\"value\":{\"type\":\"string\",\"id\":1}},\"comment\":null},\"UInt32Value\":{\"fields\":{\"value\":{\"type\":\"uint32\",\"id\":1}},\"comment\":null},\"UInt64Value\":{\"fields\":{\"value\":{\"type\":\"uint64\",\"id\":1}},\"comment\":null}}}}}}}");
52
+ export const schemaJson = JSON.parse("{\"nested\":{\"dxos\":{\"nested\":{\"credentials\":{\"nested\":{\"auth\":{\"nested\":{\"Auth\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":\"The publicKey of the target Party for these credentials.\"},\"deviceKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":\"The publicKey of the authenticating Device.\"},\"identityKey\":{\"type\":\"PubKey\",\"id\":3,\"comment\":\"The publicKey of the authenticating Identity.\"},\"feedKey\":{\"type\":\"PubKey\",\"id\":4,\"comment\":\"The publicKey of the authenticating Identity.\"},\"feedAdmit\":{\"type\":\"google.protobuf.Any\",\"id\":5,\"comment\":\"FeedAdmit message to the should be written to a control feed in case the `feedKey` is not admitted to the party.\"}},\"comment\":\"The payload for a SignedMessage sent during handshake for replication authentication.\"}}},\"greet\":{\"nested\":{\"BeginResponse\":{\"fields\":{\"info\":{\"keyType\":\"string\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"ClaimResponse\":{\"fields\":{\"id\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"rendezvousKey\":{\"type\":\"bytes\",\"id\":2,\"comment\":null}},\"comment\":null},\"Command\":{\"fields\":{\"command\":{\"type\":\"Type\",\"id\":1,\"comment\":null},\"secret\":{\"type\":\"bytes\",\"id\":2,\"comment\":null},\"params\":{\"rule\":\"repeated\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":null}},\"nested\":{\"Type\":{\"values\":{\"BEGIN\":0,\"HANDSHAKE\":1,\"NOTARIZE\":2,\"FINISH\":3,\"CLAIM\":10},\"comment\":null,\"comments\":{\"BEGIN\":null,\"HANDSHAKE\":null,\"NOTARIZE\":null,\"FINISH\":null,\"CLAIM\":null}}},\"comment\":\"A Greeter command.\"},\"HandshakeResponse\":{\"fields\":{\"nonce\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"partyKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null}},\"comment\":null},\"KeyHint\":{\"fields\":{\"publicKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"type\":{\"type\":\"KeyType\",\"id\":2,\"comment\":null}},\"comment\":null},\"NotarizeResponse\":{\"fields\":{\"copies\":{\"rule\":\"repeated\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null},\"hints\":{\"rule\":\"repeated\",\"type\":\"KeyHint\",\"id\":2,\"comment\":null}},\"comment\":null}}},\"identity\":{\"nested\":{\"DeviceInfo\":{\"fields\":{\"publicKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"displayName\":{\"type\":\"string\",\"id\":2,\"comment\":null}},\"comment\":null},\"IdentityInfo\":{\"fields\":{\"publicKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"displayName\":{\"type\":\"string\",\"id\":2,\"comment\":null}},\"comment\":null}}},\"Message\":{\"fields\":{\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"party\":{\"nested\":{\"Envelope\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"type\":\"Message\",\"id\":2,\"comment\":null}},\"comment\":null},\"FeedAdmit\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"feedKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null}},\"comment\":null},\"FeedGenesis\":{\"fields\":{\"feedKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"ownerKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null}},\"comment\":null},\"KeyAdmit\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"admitKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null},\"admitKeyType\":{\"type\":\"KeyType\",\"id\":3,\"comment\":null}},\"comment\":null},\"PartyCredential\":{\"oneofs\":{\"contents\":{\"oneof\":[\"envelope\",\"partyGenesis\",\"keyAdmit\",\"feedAdmit\",\"feedGenesis\"],\"comment\":null}},\"fields\":{\"type\":{\"type\":\"Type\",\"id\":1,\"comment\":null},\"envelope\":{\"type\":\"Envelope\",\"id\":10,\"comment\":null},\"partyGenesis\":{\"type\":\"PartyGenesis\",\"id\":11,\"comment\":null},\"keyAdmit\":{\"type\":\"KeyAdmit\",\"id\":12,\"comment\":null},\"feedAdmit\":{\"type\":\"FeedAdmit\",\"id\":13,\"comment\":null},\"feedGenesis\":{\"type\":\"FeedGenesis\",\"id\":14,\"comment\":null}},\"nested\":{\"Type\":{\"values\":{\"ENVELOPE\":0,\"PARTY_GENESIS\":1,\"FEED_GENESIS\":2,\"KEY_ADMIT\":3,\"FEED_ADMIT\":4},\"comment\":null,\"comments\":{\"ENVELOPE\":null,\"PARTY_GENESIS\":null,\"FEED_GENESIS\":null,\"KEY_ADMIT\":null,\"FEED_ADMIT\":null}}},\"comment\":null},\"PartyGenesis\":{\"fields\":{\"partyKey\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"feedKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null},\"admitKey\":{\"type\":\"PubKey\",\"id\":3,\"comment\":null},\"admitKeyType\":{\"type\":\"KeyType\",\"id\":4,\"comment\":null}},\"comment\":null},\"PartyInvitation\":{\"fields\":{\"id\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"partyKey\":{\"type\":\"PubKey\",\"id\":2,\"comment\":null},\"issuerKey\":{\"type\":\"PubKey\",\"id\":3,\"comment\":null},\"inviteeKey\":{\"type\":\"PubKey\",\"id\":4,\"comment\":null}},\"comment\":null}}},\"SignedMessage\":{\"fields\":{\"signed\":{\"rule\":\"required\",\"type\":\"Signed\",\"id\":1,\"comment\":null},\"signatures\":{\"rule\":\"repeated\",\"type\":\"Signature\",\"id\":2,\"comment\":null}},\"nested\":{\"Signature\":{\"fields\":{\"key\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"signature\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"keyChain\":{\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"Signed\":{\"fields\":{\"created\":{\"rule\":\"required\",\"type\":\"string\",\"id\":1,\"comment\":null},\"nonce\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":null}},\"comment\":null}},\"comment\":\"A generic container message used whenever messages are signed (e.g. PartyCredential)\"}}},\"halo\":{\"nested\":{\"keys\":{\"nested\":{\"KeyChain\":{\"fields\":{\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"rule\":\"required\",\"type\":\"SignedMessage\",\"id\":2,\"comment\":null},\"parents\":{\"rule\":\"repeated\",\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"KeyRecord\":{\"fields\":{\"type\":{\"rule\":\"required\",\"type\":\"KeyType\",\"id\":1,\"comment\":\"- The `KeyType` type of the key. This is often unknown for keys from other sources.\"},\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":2,\"comment\":\"- The public key as a Buffer (required).\"},\"secretKey\":{\"type\":\"PrivKey\",\"id\":3,\"comment\":\"- The secret key as a Buffer (this will never be visible outside the Keyring).\"},\"hint\":{\"type\":\"bool\",\"id\":4,\"comment\":\"- Is this key from a Greeting \\\"hint\\\"?\"},\"own\":{\"type\":\"bool\",\"id\":5,\"comment\":\"- Is this our key? Usually true if `secretKey` is present,\\nmay be false for \\\"inception keys\\\" such as the Party key.\"},\"trusted\":{\"type\":\"bool\",\"id\":6,\"comment\":\"- Is this key to be trusted?\"},\"added\":{\"type\":\"string\",\"id\":7,\"comment\":\"- An RFC-3339 date/time string for when the key was added to the Keyring.\"},\"created\":{\"type\":\"string\",\"id\":8,\"comment\":\"- An RFC-3339 date/time string for when the key was created.\"}},\"comment\":null},\"KeyRecordList\":{\"fields\":{\"keys\":{\"rule\":\"repeated\",\"type\":\"KeyRecord\",\"id\":1,\"comment\":null}},\"comment\":null},\"KeyType\":{\"values\":{\"UNKNOWN\":0,\"IDENTITY\":1,\"DEVICE\":2,\"PARTY\":3,\"FEED\":4,\"DXNS_ADDRESS\":5},\"comment\":null,\"comments\":{\"UNKNOWN\":null,\"IDENTITY\":null,\"DEVICE\":null,\"PARTY\":null,\"FEED\":null,\"DXNS_ADDRESS\":null}},\"PrivKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"PubKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}}}}}}},\"google\":{\"nested\":{\"protobuf\":{\"nested\":{\"Any\":{\"fields\":{\"type_url\":{\"type\":\"string\",\"id\":1},\"value\":{\"type\":\"bytes\",\"id\":2}},\"comment\":null},\"BoolValue\":{\"fields\":{\"value\":{\"type\":\"bool\",\"id\":1}},\"comment\":null},\"BytesValue\":{\"fields\":{\"value\":{\"type\":\"bytes\",\"id\":1}},\"comment\":null},\"DoubleValue\":{\"fields\":{\"value\":{\"type\":\"double\",\"id\":1}},\"comment\":null},\"FloatValue\":{\"fields\":{\"value\":{\"type\":\"float\",\"id\":1}},\"comment\":null},\"Int32Value\":{\"fields\":{\"value\":{\"type\":\"int32\",\"id\":1}},\"comment\":null},\"Int64Value\":{\"fields\":{\"value\":{\"type\":\"int64\",\"id\":1}},\"comment\":null},\"StringValue\":{\"fields\":{\"value\":{\"type\":\"string\",\"id\":1}},\"comment\":null},\"UInt32Value\":{\"fields\":{\"value\":{\"type\":\"uint32\",\"id\":1}},\"comment\":null},\"UInt64Value\":{\"fields\":{\"value\":{\"type\":\"uint64\",\"id\":1}},\"comment\":null}}}}}}}");
53
53
  export const schema = Schema.fromJson<TYPES, SERVICES>(schemaJson, substitutions);
@@ -1,515 +0,0 @@
1
- //
2
- // Copyright 2019 DXOS.org
3
- //
4
-
5
- // DXOS testing browser.
6
-
7
- import expect from 'expect';
8
- import moment from 'moment';
9
-
10
- import { randomBytes } from '@dxos/crypto';
11
-
12
- import { Filter, Keyring } from '../keys';
13
- import {
14
- admitsKeys,
15
- createEnvelopeMessage,
16
- createKeyAdmitMessage,
17
- createPartyGenesisMessage,
18
- PartyState
19
- } from '../party';
20
- import { codecLoop, KeyType } from '../proto';
21
- import { createAuthMessage } from './auth-message';
22
- import { PartyAuthenticator } from './authenticator';
23
-
24
- const createPartyKeyrings = async () => {
25
- // This Keyring has the full key pairs, which is the case when creating a new Party.
26
- const keyring = new Keyring();
27
- for (const type of Object.values(KeyType)) {
28
- if (typeof type === 'string') {
29
- await keyring.createKeyRecord({ type: KeyType[type] });
30
- }
31
- }
32
-
33
- const partyKey = keyring.findKey(Filter.matches({ type: KeyType.PARTY })).publicKey;
34
-
35
- /* This Keyring will have nothing but the public key of the Party. This mimics the initial state
36
- * when joining a Party, since all that is known at that time know at that time is the public key.
37
- */
38
- const bareKeyring = new Keyring();
39
- await bareKeyring.addPublicKey({
40
- publicKey: partyKey,
41
- type: KeyType.PARTY,
42
- trusted: true,
43
- own: false
44
- });
45
-
46
- return {
47
- partyKey,
48
- keyring,
49
- bareKeyring
50
- };
51
- };
52
-
53
- /* eslint-disable unused-imports/no-unused-vars */
54
- const chainToString = (chain, depth = 0) => {
55
- let ret = chain.publicKey.toHex() + '\n';
56
- if (chain.parents.length) {
57
- depth += 1;
58
- for (const parent of chain.parents) {
59
- let spaces = '';
60
- for (let i = 0; i < depth; i++) {
61
- spaces += ' ';
62
- }
63
- ret += `${spaces}-> ${chainToString(parent, depth)}`;
64
- }
65
- }
66
- return ret;
67
- };
68
- /* eslint-enable @typescript-eslint/no-unused-vars */
69
-
70
- const messageMap = (messages) => {
71
- const map = new Map();
72
- for (const message of messages) {
73
- const admits = admitsKeys(message);
74
- for (const key of admits) {
75
- map.set(key.toHex(), message);
76
- }
77
- }
78
- return map;
79
- };
80
-
81
- const getIdentityKeyChainForDevice = (keyring, devicePublicKey, messages) => {
82
- // Excludes all the FEED keys.
83
- return Keyring.buildKeyChain(devicePublicKey, messages,
84
- keyring.findKeys(Filter.matches({ type: KeyType.FEED })).map(key => key.publicKey));
85
- };
86
-
87
- it('Chain of Keys', async () => {
88
- const haloKeyring = new Keyring();
89
- const identityKey = await haloKeyring.createKeyRecord({ type: KeyType.PARTY });
90
- const deviceKeyA = await haloKeyring.createKeyRecord({ type: KeyType.DEVICE });
91
- const deviceKeyB = await haloKeyring.createKeyRecord({ type: KeyType.DEVICE });
92
- const deviceKeyC = await haloKeyring.createKeyRecord({ type: KeyType.DEVICE });
93
- const feedKeyA = await haloKeyring.createKeyRecord({ type: KeyType.FEED });
94
-
95
- const messages = new Map();
96
-
97
- // The first message in the chain in always a PartyGenesis for the Halo.
98
- messages.set(identityKey.publicKey.toHex(), createPartyGenesisMessage(haloKeyring, identityKey, feedKeyA.publicKey, deviceKeyA));
99
- messages.set(deviceKeyA.publicKey.toHex(), messages.get(identityKey.publicKey.toHex()));
100
- messages.set(feedKeyA.publicKey.toHex(), messages.get(identityKey.publicKey.toHex()));
101
-
102
- // Next is DeviceB greeted by DeviceA.
103
- messages.set(deviceKeyB.publicKey.toHex(),
104
- createEnvelopeMessage(haloKeyring, identityKey.publicKey,
105
- createKeyAdmitMessage(haloKeyring, identityKey.publicKey, deviceKeyB, [deviceKeyB]),
106
- [deviceKeyA]
107
- ));
108
-
109
- // Next is DeviceC greeted by DeviceB.
110
- messages.set(deviceKeyC.publicKey.toHex(),
111
- createEnvelopeMessage(haloKeyring, identityKey.publicKey,
112
- createKeyAdmitMessage(haloKeyring, identityKey.publicKey, deviceKeyC, [deviceKeyC]),
113
- [deviceKeyB]
114
- ));
115
-
116
- const targetKeyring = new Keyring();
117
- await targetKeyring.addPublicKey({
118
- publicKey: identityKey.publicKey,
119
- type: KeyType.IDENTITY,
120
- trusted: true,
121
- own: false
122
- });
123
-
124
- for (const deviceKey of [deviceKeyA, deviceKeyB, deviceKeyC]) {
125
- const emptyKeyring = new Keyring();
126
- const chain = Keyring.buildKeyChain(deviceKey.publicKey, messages);
127
- // In the target keyring, which only has the Identity, it should chase all the way back to the Identity.
128
- expect(identityKey.publicKey).toEqual((await targetKeyring.findTrusted(chain)).publicKey);
129
- // And in the halo, which has all the keys, it should chase straight back to this key.
130
- expect(deviceKey.publicKey).toEqual((await haloKeyring.findTrusted(chain)).publicKey);
131
- // And in an empty Keyring, we should not get anything.
132
- expect(await emptyKeyring.findTrusted(chain)).toBeUndefined();
133
- }
134
- });
135
-
136
- it('PartyAuthenticator - good direct', async () => {
137
- const { keyring, partyKey } = await createPartyKeyrings();
138
- const party = new PartyState(partyKey);
139
- const auth = new PartyAuthenticator(party);
140
-
141
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
142
-
143
- const messages = [
144
- createPartyGenesisMessage(keyring,
145
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
146
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
147
- identityKeyRecord
148
- )
149
- ];
150
-
151
- // Only add the Identity to the party keyring.
152
- await party.processMessages(messages);
153
-
154
- const wrappedCredentials = codecLoop(
155
- createAuthMessage(
156
- keyring,
157
- partyKey,
158
- identityKeyRecord,
159
- identityKeyRecord
160
- )
161
- );
162
-
163
- const ok = await auth.authenticate(wrappedCredentials.payload);
164
- expect(ok).toBe(true);
165
- });
166
-
167
- it('PartyAuthenticator - good chain', async () => {
168
- const { keyring, partyKey } = await createPartyKeyrings();
169
- const party = new PartyState(partyKey);
170
- const auth = new PartyAuthenticator(party);
171
-
172
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
173
- const deviceKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.DEVICE }));
174
- const secondDeviceKeyRecord = await keyring.createKeyRecord({ type: KeyType.DEVICE });
175
-
176
- const messages = [
177
- createPartyGenesisMessage(keyring,
178
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
179
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
180
- identityKeyRecord
181
- )
182
- ];
183
-
184
- // Only add the Identity to the party keyring.
185
- await party.processMessages(messages);
186
-
187
- const wrappedCredentials = codecLoop(
188
- createAuthMessage(
189
- keyring,
190
- partyKey,
191
- identityKeyRecord,
192
- getIdentityKeyChainForDevice(
193
- keyring,
194
- secondDeviceKeyRecord.publicKey,
195
- messageMap([
196
- ...messages,
197
- createKeyAdmitMessage(keyring, partyKey, deviceKeyRecord, [identityKeyRecord]),
198
- createKeyAdmitMessage(keyring, partyKey, secondDeviceKeyRecord, [deviceKeyRecord])
199
- ]
200
- )
201
- )
202
- )
203
- );
204
-
205
- const ok = await auth.authenticate(wrappedCredentials.payload);
206
- expect(ok).toBe(true);
207
- });
208
-
209
- it('PartyAuthenticator - bad chain', async () => {
210
- const { keyring, partyKey } = await createPartyKeyrings();
211
- const party = new PartyState(partyKey);
212
- const auth = new PartyAuthenticator(party);
213
-
214
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
215
- const deviceKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.DEVICE }));
216
- const secondDeviceKeyRecord = await keyring.createKeyRecord({ type: KeyType.DEVICE });
217
-
218
- const messages = [
219
- createPartyGenesisMessage(keyring,
220
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
221
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
222
- identityKeyRecord
223
- )
224
- ];
225
-
226
- // Only add the Identity to the party keyring.
227
- await party.processMessages(messages);
228
-
229
- // A bad chain, it doesn't track back to the Identity.
230
- const chain = getIdentityKeyChainForDevice(
231
- keyring,
232
- secondDeviceKeyRecord.publicKey,
233
- messageMap([
234
- ...messages,
235
- createKeyAdmitMessage(keyring, partyKey, deviceKeyRecord, [deviceKeyRecord]),
236
- createKeyAdmitMessage(keyring, partyKey, secondDeviceKeyRecord, [deviceKeyRecord])
237
- ]
238
- )
239
- );
240
-
241
- const wrappedCredentials = codecLoop(
242
- createAuthMessage(
243
- keyring,
244
- partyKey,
245
- identityKeyRecord,
246
- chain
247
- )
248
- );
249
-
250
- const ok = await auth.authenticate(wrappedCredentials.payload);
251
- expect(ok).toBe(false);
252
- });
253
-
254
- // TODO(dboreham): This test isn't discriminating errors because when I broke the code entirely it still passed.
255
- it('PartyAuthenticator - wrong key', async () => {
256
- const { keyring, partyKey } = await createPartyKeyrings();
257
- const party = new PartyState(partyKey);
258
- const auth = new PartyAuthenticator(party);
259
- const wrongKey = await keyring.createKeyRecord();
260
-
261
- const messages = [
262
- createPartyGenesisMessage(keyring,
263
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
264
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
265
- keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }))
266
- )
267
- ];
268
- await party.processMessages(messages);
269
-
270
- const wrappedCredentials = codecLoop(
271
- createAuthMessage(
272
- keyring,
273
- partyKey,
274
- keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY })),
275
- wrongKey
276
- )
277
- );
278
-
279
- const ok = await auth.authenticate(wrappedCredentials.payload);
280
- expect(ok).toBe(false);
281
- });
282
-
283
- it('PartyAuthenticator - wrong party', async () => {
284
- const { keyring, partyKey } = await createPartyKeyrings();
285
- const party = new PartyState(partyKey);
286
- const auth = new PartyAuthenticator(party);
287
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
288
-
289
- const messages = [
290
- createPartyGenesisMessage(keyring,
291
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
292
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
293
- identityKeyRecord
294
- )
295
- ];
296
- await party.processMessages(messages);
297
-
298
- const wrappedCredentials = codecLoop(
299
- createAuthMessage(
300
- keyring,
301
- randomBytes(32),
302
- identityKeyRecord,
303
- identityKeyRecord
304
- )
305
- );
306
-
307
- const ok = await auth.authenticate(wrappedCredentials.payload);
308
- expect(ok).toBe(false);
309
- });
310
-
311
- it('PartyAuthenticator - missing deviceKey', async () => {
312
- const { keyring, partyKey } = await createPartyKeyrings();
313
- const party = new PartyState(partyKey);
314
- const auth = new PartyAuthenticator(party);
315
-
316
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
317
-
318
- const messages = [
319
- createPartyGenesisMessage(keyring,
320
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
321
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
322
- keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }))
323
- )
324
- ];
325
- await party.processMessages(messages);
326
-
327
- const wrappedCredentials = {
328
- __type_url: 'dxos.credentials.Message',
329
- payload:
330
- keyring.sign({
331
- __type_url: 'dxos.credentials.auth.Auth',
332
- partyKey,
333
- identityKey: identityKeyRecord.publicKey
334
- }, [identityKeyRecord])
335
- };
336
-
337
- const ok = await auth.authenticate(wrappedCredentials.payload);
338
- expect(ok).toBe(false);
339
- });
340
-
341
- it('PartyAuthenticator - tampered message', async () => {
342
- const { keyring, partyKey } = await createPartyKeyrings();
343
- const party = new PartyState(partyKey);
344
- const auth = new PartyAuthenticator(party);
345
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
346
-
347
- const messages = [
348
- createPartyGenesisMessage(keyring,
349
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
350
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
351
- identityKeyRecord
352
- )
353
- ];
354
-
355
- await party.processMessages(messages);
356
-
357
- const wrappedCredentials = codecLoop(
358
- createAuthMessage(
359
- keyring,
360
- partyKey,
361
- identityKeyRecord,
362
- identityKeyRecord
363
- )
364
- );
365
-
366
- const before = await auth.authenticate(wrappedCredentials.payload);
367
- expect(before).toBe(true);
368
-
369
- wrappedCredentials.payload.signed.payload.deviceKey = randomBytes(32);
370
-
371
- const after = await auth.authenticate(wrappedCredentials.payload);
372
- expect(after).toBe(false);
373
- });
374
-
375
- it('PartyAuthenticator - tampered signature', async () => {
376
- const { keyring, partyKey } = await createPartyKeyrings();
377
- const party = new PartyState(partyKey);
378
- const auth = new PartyAuthenticator(party);
379
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
380
-
381
- const messages = [
382
- createPartyGenesisMessage(keyring,
383
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
384
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
385
- identityKeyRecord
386
- )
387
- ];
388
-
389
- await party.processMessages(messages);
390
-
391
- const wrappedCredentials = codecLoop(
392
- createAuthMessage(
393
- keyring,
394
- partyKey,
395
- identityKeyRecord,
396
- identityKeyRecord
397
- )
398
- );
399
-
400
- const before = await auth.authenticate(wrappedCredentials.payload);
401
- expect(before).toBe(true);
402
-
403
- wrappedCredentials.payload.signatures[0].signature = randomBytes(64);
404
-
405
- const after = await auth.authenticate(wrappedCredentials.payload);
406
- expect(after).toBe(false);
407
- });
408
-
409
- it('PartyAuthenticator - signature too old', async () => {
410
- const { keyring, partyKey } = await createPartyKeyrings();
411
- const party = new PartyState(partyKey);
412
- const auth = new PartyAuthenticator(party);
413
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
414
- const deviceKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.DEVICE }));
415
-
416
- const messages = [
417
- createPartyGenesisMessage(keyring,
418
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
419
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
420
- identityKeyRecord
421
- )
422
- ];
423
-
424
- await party.processMessages(messages);
425
-
426
- const wrappedCredentials = {
427
- __type_url: 'dxos.credentials.Message',
428
- payload:
429
- keyring.sign({
430
- __type_url: 'dxos.credentials.auth.Auth',
431
- partyKey,
432
- identityKey: identityKeyRecord.publicKey,
433
- deviceKey: deviceKeyRecord.publicKey
434
- },
435
- [identityKeyRecord],
436
- null,
437
- moment().subtract(2, 'days').format('YYYY-MM-DDTHH:mm:ssZ')
438
- )
439
- };
440
-
441
- const ok = await auth.authenticate(wrappedCredentials.payload);
442
- expect(ok).toBe(false);
443
- });
444
-
445
- it('PartyAuthenticator - signature too far in future', async () => {
446
- const { keyring, partyKey } = await createPartyKeyrings();
447
- const party = new PartyState(partyKey);
448
- const auth = new PartyAuthenticator(party);
449
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
450
- const deviceKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.DEVICE }));
451
-
452
- const messages = [
453
- createPartyGenesisMessage(keyring,
454
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
455
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
456
- identityKeyRecord
457
- )
458
- ];
459
-
460
- await party.processMessages(messages);
461
-
462
- const wrappedCredentials = {
463
- __type_url: 'dxos.credentials.Message',
464
- payload:
465
- keyring.sign({
466
- __type_url: 'dxos.credentials.auth.Auth',
467
- partyKey,
468
- identityKey: identityKeyRecord.publicKey,
469
- deviceKey: deviceKeyRecord.publicKey
470
- },
471
- [identityKeyRecord],
472
- null,
473
- moment().add(2, 'days').format('YYYY-MM-DDTHH:mm:ssZ')
474
- )
475
- };
476
-
477
- const ok = await auth.authenticate(wrappedCredentials.payload);
478
- expect(ok).toBe(false);
479
- });
480
-
481
- it('PartyAuthenticator - signature date invalid', async () => {
482
- const { keyring, partyKey } = await createPartyKeyrings();
483
- const party = new PartyState(partyKey);
484
- const auth = new PartyAuthenticator(party);
485
- const identityKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.IDENTITY }));
486
- const deviceKeyRecord = keyring.findKey(Keyring.signingFilter({ type: KeyType.DEVICE }));
487
-
488
- const messages = [
489
- createPartyGenesisMessage(keyring,
490
- keyring.findKey(Filter.matches({ type: KeyType.PARTY })),
491
- keyring.findKey(Keyring.signingFilter({ type: KeyType.FEED })).publicKey,
492
- identityKeyRecord
493
- )
494
- ];
495
-
496
- await party.processMessages(messages);
497
-
498
- const wrappedCredentials = {
499
- __type_url: 'dxos.credentials.Message',
500
- payload:
501
- keyring.sign({
502
- __type_url: 'dxos.credentials.auth.Auth',
503
- partyKey,
504
- identityKey: identityKeyRecord.publicKey,
505
- deviceKey: deviceKeyRecord.publicKey
506
- },
507
- [identityKeyRecord],
508
- null,
509
- 'INVALID'
510
- )
511
- };
512
-
513
- const ok = await auth.authenticate(wrappedCredentials.payload);
514
- expect(ok).toBe(false);
515
- });