@dxos/credentials 0.8.3 → 0.8.4-main.03d5cd7b56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/{browser → neutral}/index.mjs +185 -379
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/types/src/credentials/assertions.d.ts +1 -1
- package/dist/types/src/credentials/assertions.d.ts.map +1 -1
- package/dist/types/src/credentials/credential-factory.d.ts +4 -4
- package/dist/types/src/credentials/credential-factory.d.ts.map +1 -1
- package/dist/types/src/credentials/credential-generator.d.ts +3 -3
- package/dist/types/src/credentials/credential-generator.d.ts.map +1 -1
- package/dist/types/src/credentials/signing.d.ts.map +1 -1
- package/dist/types/src/credentials/verifier.d.ts.map +1 -1
- package/dist/types/src/did.d.ts +1 -1
- package/dist/types/src/did.d.ts.map +1 -1
- package/dist/types/src/graph/credential-graph.d.ts.map +1 -1
- package/dist/types/src/passcode.d.ts.map +1 -1
- package/dist/types/src/presentations/presentation.d.ts.map +1 -1
- package/dist/types/src/presentations/signing.d.ts.map +1 -1
- package/dist/types/src/presentations/verifier.d.ts.map +1 -1
- package/dist/types/src/processor/device-state-machine.d.ts +2 -2
- package/dist/types/src/processor/device-state-machine.d.ts.map +1 -1
- package/dist/types/src/processor/index.d.ts +1 -1
- package/dist/types/src/processor/index.d.ts.map +1 -1
- package/dist/types/src/processor/profile-state-machine.d.ts +2 -2
- package/dist/types/src/processor/profile-state-machine.d.ts.map +1 -1
- package/dist/types/src/seedphrase.d.ts.map +1 -1
- package/dist/types/src/state-machine/feed-state-machine.d.ts.map +1 -1
- package/dist/types/src/state-machine/invitation-state-machine.d.ts.map +1 -1
- package/dist/types/src/state-machine/member-state-machine.d.ts +1 -1
- package/dist/types/src/state-machine/member-state-machine.d.ts.map +1 -1
- package/dist/types/src/state-machine/space-state-machine.d.ts +8 -2
- package/dist/types/src/state-machine/space-state-machine.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/docs/README.md +17 -17
- package/moon.yml +12 -0
- package/package.json +20 -23
- package/src/credentials/assertions.ts +1 -1
- package/src/credentials/credential-factory.ts +5 -5
- package/src/credentials/credential-generator.ts +6 -1
- package/src/credentials/signing.ts +12 -0
- package/src/did.ts +2 -2
- package/src/presentations/json-encoding.test.ts +1 -1
- package/src/presentations/presentation.ts +1 -1
- package/src/presentations/verifier.test.ts +1 -1
- package/src/presentations/verifier.ts +1 -1
- package/src/processor/device-state-machine.ts +3 -3
- package/src/processor/index.ts +1 -1
- package/src/processor/profile-state-machine.ts +3 -3
- package/src/state-machine/invitation-state-machine.test.ts +2 -2
- package/src/state-machine/member-state-machine.test.ts +1 -1
- package/src/state-machine/member-state-machine.ts +1 -1
- package/src/state-machine/space-state-machine.test.ts +244 -2
- package/src/state-machine/space-state-machine.ts +33 -9
- package/vitest.config.ts +7 -3
- package/.eslintrc.cjs +0 -7
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/node/index.cjs +0 -1894
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node-esm/index.mjs +0 -1870
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/project.json +0 -27
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@dxos/node-std/globals";
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// src/did.ts
|
|
4
4
|
import { subtleCrypto } from "@dxos/crypto";
|
|
5
|
-
import {
|
|
5
|
+
import { IdentityDid, PublicKey } from "@dxos/keys";
|
|
6
6
|
import { ComplexMap } from "@dxos/util";
|
|
7
7
|
var IDENTITY_DIDS_CACHE = new ComplexMap(PublicKey.hash);
|
|
8
8
|
var createDidFromIdentityKey = async (identityKey) => {
|
|
@@ -17,31 +17,23 @@ var createDidFromIdentityKey = async (identityKey) => {
|
|
|
17
17
|
return identityDid;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// src/invitations.ts
|
|
21
21
|
var defaultSecretProvider = async () => Buffer.from("0000");
|
|
22
22
|
var defaultSecretValidator = async (invitation, secret) => true;
|
|
23
23
|
|
|
24
|
-
//
|
|
24
|
+
// src/seedphrase.ts
|
|
25
25
|
import { generateMnemonic, mnemonicToSeedSync } from "bip39";
|
|
26
26
|
import { createKeyPair } from "@dxos/crypto";
|
|
27
27
|
import { invariant } from "@dxos/invariant";
|
|
28
|
-
var __dxlog_file = "/
|
|
28
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/halo/credentials/src/seedphrase.ts";
|
|
29
29
|
var generateSeedPhrase = () => generateMnemonic();
|
|
30
30
|
var keyPairFromSeedPhrase = (seedPhrase) => {
|
|
31
|
-
invariant(seedPhrase, void 0, {
|
|
32
|
-
F: __dxlog_file,
|
|
33
|
-
L: 20,
|
|
34
|
-
S: void 0,
|
|
35
|
-
A: [
|
|
36
|
-
"seedPhrase",
|
|
37
|
-
""
|
|
38
|
-
]
|
|
39
|
-
});
|
|
31
|
+
invariant(seedPhrase, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0, A: ["seedPhrase", ""] });
|
|
40
32
|
const seed = mnemonicToSeedSync(seedPhrase);
|
|
41
33
|
return createKeyPair(seed);
|
|
42
34
|
};
|
|
43
35
|
|
|
44
|
-
//
|
|
36
|
+
// src/passcode.ts
|
|
45
37
|
var generatePasscode = (length = 4) => {
|
|
46
38
|
let passcode = "";
|
|
47
39
|
for (let i = 0; i < length; i++) {
|
|
@@ -50,7 +42,7 @@ var generatePasscode = (length = 4) => {
|
|
|
50
42
|
return passcode;
|
|
51
43
|
};
|
|
52
44
|
|
|
53
|
-
//
|
|
45
|
+
// src/credentials/signing.ts
|
|
54
46
|
import stableStringify from "json-stable-stringify";
|
|
55
47
|
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
56
48
|
import { Timeframe } from "@dxos/timeframe";
|
|
@@ -68,6 +60,14 @@ var getCredentialProofPayload = (credential) => {
|
|
|
68
60
|
delete copy.parentCredentialIds;
|
|
69
61
|
}
|
|
70
62
|
delete copy.id;
|
|
63
|
+
const assertion = copy.subject?.assertion;
|
|
64
|
+
if (assertion) {
|
|
65
|
+
for (const key of Object.keys(assertion)) {
|
|
66
|
+
if (Array.isArray(assertion[key]) && assertion[key].length === 0) {
|
|
67
|
+
delete assertion[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
71
|
return Buffer.from(canonicalStringify(copy));
|
|
72
72
|
};
|
|
73
73
|
var canonicalStringify = (obj) => stableStringify(obj, {
|
|
@@ -114,7 +114,7 @@ var truncateKey = (key) => {
|
|
|
114
114
|
return `${str.substring(0, 4)}...${str.substring(str.length - 4)}`;
|
|
115
115
|
};
|
|
116
116
|
|
|
117
|
-
//
|
|
117
|
+
// src/presentations/signing.ts
|
|
118
118
|
var getPresentationProofPayload = (credentials, proof) => {
|
|
119
119
|
const copy = {
|
|
120
120
|
credentials: credentials.map((credential) => removeEmptyParentCredentialIds(credential)),
|
|
@@ -142,7 +142,7 @@ var removeEmptyParentCredentialIds = (credential) => {
|
|
|
142
142
|
return copy;
|
|
143
143
|
};
|
|
144
144
|
|
|
145
|
-
//
|
|
145
|
+
// src/credentials/assertions.ts
|
|
146
146
|
var getCredentialAssertion = (credential) => credential.subject.assertion;
|
|
147
147
|
var isValidAuthorizedDeviceCredential = (credential, identityKey, deviceKey) => {
|
|
148
148
|
const assertion = getCredentialAssertion(credential);
|
|
@@ -151,12 +151,12 @@ var isValidAuthorizedDeviceCredential = (credential, identityKey, deviceKey) =>
|
|
|
151
151
|
var checkCredentialType = (credential, type) => credential.subject.assertion["@type"] === type;
|
|
152
152
|
var credentialTypeFilter = (type) => (credential) => checkCredentialType(credential, type);
|
|
153
153
|
|
|
154
|
-
//
|
|
154
|
+
// src/credentials/credential-factory.ts
|
|
155
155
|
import { subtleCrypto as subtleCrypto2 } from "@dxos/crypto";
|
|
156
156
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
157
157
|
import { PublicKey as PublicKey3 } from "@dxos/keys";
|
|
158
158
|
|
|
159
|
-
//
|
|
159
|
+
// src/credentials/verifier.ts
|
|
160
160
|
import { verifySignature } from "@dxos/crypto";
|
|
161
161
|
var SIGNATURE_TYPE_ED25519 = "ED25519Signature";
|
|
162
162
|
var verifyCredential = async (credential) => {
|
|
@@ -225,38 +225,14 @@ var verifyChain = async (chain, authority, subject) => {
|
|
|
225
225
|
};
|
|
226
226
|
};
|
|
227
227
|
|
|
228
|
-
//
|
|
229
|
-
var __dxlog_file2 = "/
|
|
228
|
+
// src/credentials/credential-factory.ts
|
|
229
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/halo/credentials/src/credentials/credential-factory.ts";
|
|
230
230
|
var createCredential = async ({ signer, issuer, subject, assertion, signingKey, chain, nonce, parentCredentialIds }) => {
|
|
231
|
-
invariant2(assertion["@type"], "Invalid assertion.", {
|
|
232
|
-
|
|
233
|
-
L: 48,
|
|
234
|
-
S: void 0,
|
|
235
|
-
A: [
|
|
236
|
-
"assertion['@type']",
|
|
237
|
-
"'Invalid assertion.'"
|
|
238
|
-
]
|
|
239
|
-
});
|
|
240
|
-
invariant2(!!signingKey === !!chain, "Chain must be provided if and only if the signing key differs from the issuer.", {
|
|
241
|
-
F: __dxlog_file2,
|
|
242
|
-
L: 49,
|
|
243
|
-
S: void 0,
|
|
244
|
-
A: [
|
|
245
|
-
"!!signingKey === !!chain",
|
|
246
|
-
"'Chain must be provided if and only if the signing key differs from the issuer.'"
|
|
247
|
-
]
|
|
248
|
-
});
|
|
231
|
+
invariant2(assertion["@type"], "Invalid assertion.", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 12, S: void 0, A: ["assertion['@type']", "'Invalid assertion.'"] });
|
|
232
|
+
invariant2(!!signingKey === !!chain, "Chain must be provided if and only if the signing key differs from the issuer.", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 13, S: void 0, A: ["!!signingKey === !!chain", "'Chain must be provided if and only if the signing key differs from the issuer.'"] });
|
|
249
233
|
if (chain) {
|
|
250
234
|
const result = await verifyChain(chain, issuer, signingKey);
|
|
251
|
-
invariant2(result.kind === "pass", "Invalid chain.", {
|
|
252
|
-
F: __dxlog_file2,
|
|
253
|
-
L: 52,
|
|
254
|
-
S: void 0,
|
|
255
|
-
A: [
|
|
256
|
-
"result.kind === 'pass'",
|
|
257
|
-
"'Invalid chain.'"
|
|
258
|
-
]
|
|
259
|
-
});
|
|
235
|
+
invariant2(result.kind === "pass", "Invalid chain.", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 16, S: void 0, A: ["result.kind === 'pass'", "'Invalid chain.'"] });
|
|
260
236
|
}
|
|
261
237
|
const credential = {
|
|
262
238
|
issuer,
|
|
@@ -313,10 +289,13 @@ var createCredentialSignerWithChain = (signer, chain, signingKey) => ({
|
|
|
313
289
|
})
|
|
314
290
|
});
|
|
315
291
|
|
|
316
|
-
//
|
|
317
|
-
import { AdmittedFeed, SpaceMember } from "@dxos/protocols/proto/dxos/halo/credentials";
|
|
292
|
+
// src/credentials/credential-generator.ts
|
|
293
|
+
import { AdmittedFeed, MembershipPolicy, SpaceMember } from "@dxos/protocols/proto/dxos/halo/credentials";
|
|
318
294
|
import { Timeframe as Timeframe2 } from "@dxos/timeframe";
|
|
319
295
|
var CredentialGenerator = class {
|
|
296
|
+
_signer;
|
|
297
|
+
_identityKey;
|
|
298
|
+
_deviceKey;
|
|
320
299
|
constructor(_signer, _identityKey, _deviceKey) {
|
|
321
300
|
this._signer = _signer;
|
|
322
301
|
this._identityKey = _identityKey;
|
|
@@ -325,7 +304,7 @@ var CredentialGenerator = class {
|
|
|
325
304
|
/**
|
|
326
305
|
* Create genesis messages for new Space.
|
|
327
306
|
*/
|
|
328
|
-
async createSpaceGenesis(spaceKey, controlKey, creatorProfile) {
|
|
307
|
+
async createSpaceGenesis(spaceKey, controlKey, creatorProfile, membershipPolicy = MembershipPolicy.INVITE) {
|
|
329
308
|
return [
|
|
330
309
|
await createCredential({
|
|
331
310
|
signer: this._signer,
|
|
@@ -333,7 +312,8 @@ var CredentialGenerator = class {
|
|
|
333
312
|
subject: spaceKey,
|
|
334
313
|
assertion: {
|
|
335
314
|
"@type": "dxos.halo.credentials.SpaceGenesis",
|
|
336
|
-
spaceKey
|
|
315
|
+
spaceKey,
|
|
316
|
+
membershipPolicy
|
|
337
317
|
}
|
|
338
318
|
}),
|
|
339
319
|
await createCredential({
|
|
@@ -460,7 +440,7 @@ var createDeviceAuthorization = async (signer, identityKey, deviceKey) => {
|
|
|
460
440
|
credential
|
|
461
441
|
}));
|
|
462
442
|
};
|
|
463
|
-
var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFeedKey, role = SpaceMember.Role.ADMIN, membershipChainHeads = [], profile, invitationCredentialId) => {
|
|
443
|
+
var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFeedKey, role = SpaceMember.Role.ADMIN, membershipChainHeads = [], profile, invitationCredentialId, tags) => {
|
|
464
444
|
const credentials = await Promise.all([
|
|
465
445
|
await signer.createCredential({
|
|
466
446
|
subject: identityKey,
|
|
@@ -471,7 +451,8 @@ var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFe
|
|
|
471
451
|
role,
|
|
472
452
|
profile,
|
|
473
453
|
genesisFeedKey,
|
|
474
|
-
invitationCredentialId
|
|
454
|
+
invitationCredentialId,
|
|
455
|
+
tags: tags ?? []
|
|
475
456
|
}
|
|
476
457
|
})
|
|
477
458
|
]);
|
|
@@ -516,7 +497,7 @@ var createCancelDelegatedSpaceInvitationCredential = async (signer, subject, inv
|
|
|
516
497
|
};
|
|
517
498
|
};
|
|
518
499
|
|
|
519
|
-
//
|
|
500
|
+
// src/presentations/presentation.ts
|
|
520
501
|
var signPresentation = async ({ presentation, signer, signerKey, chain, nonce }) => {
|
|
521
502
|
const proof = {
|
|
522
503
|
type: SIGNATURE_TYPE_ED25519,
|
|
@@ -539,7 +520,7 @@ var signPresentation = async ({ presentation, signer, signerKey, chain, nonce })
|
|
|
539
520
|
};
|
|
540
521
|
};
|
|
541
522
|
|
|
542
|
-
//
|
|
523
|
+
// src/presentations/verifier.ts
|
|
543
524
|
import { verifySignature as verifySignature2 } from "@dxos/crypto";
|
|
544
525
|
var verifyPresentation = async (presentation) => {
|
|
545
526
|
const errors = [];
|
|
@@ -623,24 +604,25 @@ var verifyPresentationSignature = async (presentation, proof) => {
|
|
|
623
604
|
};
|
|
624
605
|
};
|
|
625
606
|
|
|
626
|
-
//
|
|
607
|
+
// src/state-machine/space-state-machine.ts
|
|
627
608
|
import { runInContextAsync, synchronized } from "@dxos/async";
|
|
628
609
|
import { Context } from "@dxos/context";
|
|
629
610
|
import { PublicKey as PublicKey8 } from "@dxos/keys";
|
|
630
611
|
import { log as log3 } from "@dxos/log";
|
|
631
|
-
import { SpaceMember as SpaceMember3 } from "@dxos/protocols/proto/dxos/halo/credentials";
|
|
612
|
+
import { MembershipPolicy as MembershipPolicy2, SpaceMember as SpaceMember3 } from "@dxos/protocols/proto/dxos/halo/credentials";
|
|
632
613
|
import { Callback as Callback4, ComplexMap as ComplexMap6, ComplexSet as ComplexSet3 } from "@dxos/util";
|
|
633
614
|
|
|
634
|
-
//
|
|
615
|
+
// src/state-machine/feed-state-machine.ts
|
|
635
616
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
636
617
|
import { PublicKey as PublicKey4 } from "@dxos/keys";
|
|
637
618
|
import { Callback, ComplexMap as ComplexMap2 } from "@dxos/util";
|
|
638
|
-
var __dxlog_file3 = "/
|
|
619
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/halo/credentials/src/state-machine/feed-state-machine.ts";
|
|
639
620
|
var FeedStateMachine = class {
|
|
621
|
+
_spaceKey;
|
|
622
|
+
_feeds = new ComplexMap2(PublicKey4.hash);
|
|
623
|
+
onFeedAdmitted = new Callback();
|
|
640
624
|
constructor(_spaceKey) {
|
|
641
625
|
this._spaceKey = _spaceKey;
|
|
642
|
-
this._feeds = new ComplexMap2(PublicKey4.hash);
|
|
643
|
-
this.onFeedAdmitted = new Callback();
|
|
644
626
|
}
|
|
645
627
|
get feeds() {
|
|
646
628
|
return this._feeds;
|
|
@@ -653,24 +635,8 @@ var FeedStateMachine = class {
|
|
|
653
635
|
*/
|
|
654
636
|
async process(credential, fromFeed) {
|
|
655
637
|
const assertion = getCredentialAssertion(credential);
|
|
656
|
-
invariant3(assertion["@type"] === "dxos.halo.credentials.AdmittedFeed", void 0, {
|
|
657
|
-
|
|
658
|
-
L: 47,
|
|
659
|
-
S: this,
|
|
660
|
-
A: [
|
|
661
|
-
"assertion['@type'] === 'dxos.halo.credentials.AdmittedFeed'",
|
|
662
|
-
""
|
|
663
|
-
]
|
|
664
|
-
});
|
|
665
|
-
invariant3(assertion.spaceKey.equals(this._spaceKey), void 0, {
|
|
666
|
-
F: __dxlog_file3,
|
|
667
|
-
L: 48,
|
|
668
|
-
S: this,
|
|
669
|
-
A: [
|
|
670
|
-
"assertion.spaceKey.equals(this._spaceKey)",
|
|
671
|
-
""
|
|
672
|
-
]
|
|
673
|
-
});
|
|
638
|
+
invariant3(assertion["@type"] === "dxos.halo.credentials.AdmittedFeed", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 28, S: this, A: ["assertion['@type'] === 'dxos.halo.credentials.AdmittedFeed'", ""] });
|
|
639
|
+
invariant3(assertion.spaceKey.equals(this._spaceKey), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 29, S: this, A: ["assertion.spaceKey.equals(this._spaceKey)", ""] });
|
|
674
640
|
const info = {
|
|
675
641
|
key: credential.subject.id,
|
|
676
642
|
credential,
|
|
@@ -682,17 +648,15 @@ var FeedStateMachine = class {
|
|
|
682
648
|
}
|
|
683
649
|
};
|
|
684
650
|
|
|
685
|
-
//
|
|
651
|
+
// src/state-machine/invitation-state-machine.ts
|
|
686
652
|
import { PublicKey as PublicKey5 } from "@dxos/keys";
|
|
687
653
|
import { Callback as Callback2, ComplexMap as ComplexMap3, ComplexSet } from "@dxos/util";
|
|
688
654
|
var InvitationStateMachine = class {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
this.onDelegatedInvitationRemoved = new Callback2();
|
|
695
|
-
}
|
|
655
|
+
_invitations = new ComplexMap3(PublicKey5.hash);
|
|
656
|
+
_redeemedInvitationCredentialIds = new ComplexSet(PublicKey5.hash);
|
|
657
|
+
_cancelledInvitationCredentialIds = new ComplexSet(PublicKey5.hash);
|
|
658
|
+
onDelegatedInvitation = new Callback2();
|
|
659
|
+
onDelegatedInvitationRemoved = new Callback2();
|
|
696
660
|
get invitations() {
|
|
697
661
|
return this._invitations;
|
|
698
662
|
}
|
|
@@ -752,37 +716,54 @@ var InvitationStateMachine = class {
|
|
|
752
716
|
}
|
|
753
717
|
};
|
|
754
718
|
|
|
755
|
-
//
|
|
719
|
+
// src/state-machine/member-state-machine.ts
|
|
756
720
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
757
721
|
import { PublicKey as PublicKey7 } from "@dxos/keys";
|
|
758
722
|
import { log as log2 } from "@dxos/log";
|
|
759
723
|
import { SpaceMember as SpaceMember2 } from "@dxos/protocols/proto/dxos/halo/credentials";
|
|
760
724
|
import { ComplexMap as ComplexMap5 } from "@dxos/util";
|
|
761
725
|
|
|
762
|
-
//
|
|
726
|
+
// src/graph/credential-graph.ts
|
|
763
727
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
764
728
|
import { PublicKey as PublicKey6 } from "@dxos/keys";
|
|
765
729
|
import { log } from "@dxos/log";
|
|
766
730
|
import { Callback as Callback3, ComplexMap as ComplexMap4, ComplexSet as ComplexSet2 } from "@dxos/util";
|
|
767
|
-
var __dxlog_file4 = "/
|
|
731
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/halo/credentials/src/graph/credential-graph.ts";
|
|
768
732
|
var CredentialGraph = class {
|
|
733
|
+
_stateHandler;
|
|
734
|
+
/**
|
|
735
|
+
* Local ids are used during traversals.
|
|
736
|
+
*/
|
|
737
|
+
_vertexIdGenerator = 1;
|
|
738
|
+
/**
|
|
739
|
+
* All credentials without parent references are connected to the root.
|
|
740
|
+
*/
|
|
741
|
+
_root = {
|
|
742
|
+
id: -1,
|
|
743
|
+
parents: [],
|
|
744
|
+
children: []
|
|
745
|
+
};
|
|
746
|
+
/**
|
|
747
|
+
* A credential which is not a parent of any other credential has the sentinel as a child.
|
|
748
|
+
* Sentinel is a virtual merge-point of all credentials.
|
|
749
|
+
*/
|
|
750
|
+
_sentinel = {
|
|
751
|
+
id: -2,
|
|
752
|
+
parents: [],
|
|
753
|
+
children: []
|
|
754
|
+
};
|
|
755
|
+
/**
|
|
756
|
+
* Vertex references are used for fast credential inserts into the graph.
|
|
757
|
+
*/
|
|
758
|
+
_vertexByCredentialId = new ComplexMap4(PublicKey6.hash);
|
|
759
|
+
/**
|
|
760
|
+
* The current state of the graph.
|
|
761
|
+
*/
|
|
762
|
+
_subjectToVertex = new ComplexMap4(PublicKey6.hash);
|
|
763
|
+
_subjectToState = new ComplexMap4(PublicKey6.hash);
|
|
764
|
+
onSubjectStateChanged = new Callback3();
|
|
769
765
|
constructor(_stateHandler) {
|
|
770
766
|
this._stateHandler = _stateHandler;
|
|
771
|
-
this._vertexIdGenerator = 1;
|
|
772
|
-
this._root = {
|
|
773
|
-
id: -1,
|
|
774
|
-
parents: [],
|
|
775
|
-
children: []
|
|
776
|
-
};
|
|
777
|
-
this._sentinel = {
|
|
778
|
-
id: -2,
|
|
779
|
-
parents: [],
|
|
780
|
-
children: []
|
|
781
|
-
};
|
|
782
|
-
this._vertexByCredentialId = new ComplexMap4(PublicKey6.hash);
|
|
783
|
-
this._subjectToVertex = new ComplexMap4(PublicKey6.hash);
|
|
784
|
-
this._subjectToState = new ComplexMap4(PublicKey6.hash);
|
|
785
|
-
this.onSubjectStateChanged = new Callback3();
|
|
786
767
|
}
|
|
787
768
|
getSubjectState(subjectId) {
|
|
788
769
|
return this._subjectToState.get(subjectId);
|
|
@@ -818,12 +799,7 @@ var CredentialGraph = class {
|
|
|
818
799
|
log.error("credential skipped because of the unknown parent", {
|
|
819
800
|
credential,
|
|
820
801
|
parentId
|
|
821
|
-
}, {
|
|
822
|
-
F: __dxlog_file4,
|
|
823
|
-
L: 72,
|
|
824
|
-
S: this,
|
|
825
|
-
C: (f, a) => f(...a)
|
|
826
|
-
});
|
|
802
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 70, S: this });
|
|
827
803
|
continue;
|
|
828
804
|
}
|
|
829
805
|
parentVertex.children.push(newVertex);
|
|
@@ -840,29 +816,13 @@ var CredentialGraph = class {
|
|
|
840
816
|
if (sentinelIdx >= 0) {
|
|
841
817
|
vertex.children.splice(sentinelIdx, 1);
|
|
842
818
|
const vertexInSentinelIdx = this._sentinel.parents.indexOf(vertex);
|
|
843
|
-
invariant4(vertexInSentinelIdx >= 0, void 0, {
|
|
844
|
-
F: __dxlog_file4,
|
|
845
|
-
L: 90,
|
|
846
|
-
S: this,
|
|
847
|
-
A: [
|
|
848
|
-
"vertexInSentinelIdx >= 0",
|
|
849
|
-
""
|
|
850
|
-
]
|
|
851
|
-
});
|
|
819
|
+
invariant4(vertexInSentinelIdx >= 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 90, S: this, A: ["vertexInSentinelIdx >= 0", ""] });
|
|
852
820
|
this._sentinel.parents.splice(vertexInSentinelIdx, 1);
|
|
853
821
|
}
|
|
854
822
|
}
|
|
855
823
|
async _onVertexInserted(newVertex) {
|
|
856
824
|
const { credential, assertion } = newVertex;
|
|
857
|
-
invariant4(credential, void 0, {
|
|
858
|
-
F: __dxlog_file4,
|
|
859
|
-
L: 97,
|
|
860
|
-
S: this,
|
|
861
|
-
A: [
|
|
862
|
-
"credential",
|
|
863
|
-
""
|
|
864
|
-
]
|
|
865
|
-
});
|
|
825
|
+
invariant4(credential, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 96, S: this, A: ["credential", ""] });
|
|
866
826
|
let changedSubjects = [];
|
|
867
827
|
const isUpdateAppliedOnTopOfThePreviousState = this._sentinel.parents.length === 1;
|
|
868
828
|
if (isUpdateAppliedOnTopOfThePreviousState) {
|
|
@@ -899,21 +859,11 @@ var CredentialGraph = class {
|
|
|
899
859
|
const path = paths.pop();
|
|
900
860
|
log("visit vertex", {
|
|
901
861
|
id: path.head.id
|
|
902
|
-
}, {
|
|
903
|
-
F: __dxlog_file4,
|
|
904
|
-
L: 132,
|
|
905
|
-
S: this,
|
|
906
|
-
C: (f, a) => f(...a)
|
|
907
|
-
});
|
|
862
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 131, S: this });
|
|
908
863
|
this._updatePathState(path);
|
|
909
864
|
const convergedPaths = this._handleMergePoint(paths, pendingPaths, path);
|
|
910
865
|
if (convergedPaths == null) {
|
|
911
|
-
log("waiting for other paths", void 0, {
|
|
912
|
-
F: __dxlog_file4,
|
|
913
|
-
L: 136,
|
|
914
|
-
S: this,
|
|
915
|
-
C: (f, a) => f(...a)
|
|
916
|
-
});
|
|
866
|
+
log("waiting for other paths", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 137, S: this });
|
|
917
867
|
continue;
|
|
918
868
|
}
|
|
919
869
|
const mergeResult = this._mergePaths(convergedPaths);
|
|
@@ -937,12 +887,7 @@ var CredentialGraph = class {
|
|
|
937
887
|
path: toChosenPath(p),
|
|
938
888
|
head: p.head.id
|
|
939
889
|
}))
|
|
940
|
-
}, {
|
|
941
|
-
F: __dxlog_file4,
|
|
942
|
-
L: 155,
|
|
943
|
-
S: this,
|
|
944
|
-
C: (f, a) => f(...a)
|
|
945
|
-
});
|
|
890
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 156, S: this });
|
|
946
891
|
}
|
|
947
892
|
return this._setCurrentState(lastPath);
|
|
948
893
|
}
|
|
@@ -963,12 +908,7 @@ var CredentialGraph = class {
|
|
|
963
908
|
path: toChosenPath(path),
|
|
964
909
|
overrides: path?.stateOverrides?.mapValues((v) => this._stateHandler.toLogString(v.assertion))
|
|
965
910
|
}))
|
|
966
|
-
}), {
|
|
967
|
-
F: __dxlog_file4,
|
|
968
|
-
L: 175,
|
|
969
|
-
S: this,
|
|
970
|
-
C: (f, a) => f(...a)
|
|
971
|
-
});
|
|
911
|
+
}), { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 175, S: this });
|
|
972
912
|
const clearedPending = convergedPaths.filter((l) => !mergeResult.replay.includes(l));
|
|
973
913
|
pendingPaths.set(convergedPaths[0].head.id, clearedPending);
|
|
974
914
|
}
|
|
@@ -980,12 +920,7 @@ var CredentialGraph = class {
|
|
|
980
920
|
return null;
|
|
981
921
|
}
|
|
982
922
|
if (path.head.id === this._sentinel.id && paths.length > 0) {
|
|
983
|
-
log("waiting for all the active paths to converge on the sentinel", void 0, {
|
|
984
|
-
F: __dxlog_file4,
|
|
985
|
-
L: 199,
|
|
986
|
-
S: this,
|
|
987
|
-
C: (f, a) => f(...a)
|
|
988
|
-
});
|
|
923
|
+
log("waiting for all the active paths to converge on the sentinel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 194, S: this });
|
|
989
924
|
return null;
|
|
990
925
|
}
|
|
991
926
|
pendingPaths.delete(path.head.id);
|
|
@@ -1010,12 +945,7 @@ var CredentialGraph = class {
|
|
|
1010
945
|
log("path state updated", () => ({
|
|
1011
946
|
subject: updatedSubject,
|
|
1012
947
|
newState: this._stateHandler.toLogString(path.head.assertion)
|
|
1013
|
-
}), {
|
|
1014
|
-
F: __dxlog_file4,
|
|
1015
|
-
L: 223,
|
|
1016
|
-
S: this,
|
|
1017
|
-
C: (f, a) => f(...a)
|
|
1018
|
-
});
|
|
948
|
+
}), { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 217, S: this });
|
|
1019
949
|
}
|
|
1020
950
|
}
|
|
1021
951
|
_forkTraversal(paths, path) {
|
|
@@ -1025,12 +955,7 @@ var CredentialGraph = class {
|
|
|
1025
955
|
log("edge traversal", {
|
|
1026
956
|
from: path.head.id,
|
|
1027
957
|
to: choice.id
|
|
1028
|
-
}, {
|
|
1029
|
-
F: __dxlog_file4,
|
|
1030
|
-
L: 234,
|
|
1031
|
-
S: this,
|
|
1032
|
-
C: (f, a) => f(...a)
|
|
1033
|
-
});
|
|
958
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 227, S: this });
|
|
1034
959
|
const fork = {
|
|
1035
960
|
forkPoint: path,
|
|
1036
961
|
chosenPath: {
|
|
@@ -1123,15 +1048,7 @@ var CredentialGraph = class {
|
|
|
1123
1048
|
return path;
|
|
1124
1049
|
}
|
|
1125
1050
|
_mergePaths(convergedPaths) {
|
|
1126
|
-
invariant4(convergedPaths.length >= 1, void 0, {
|
|
1127
|
-
F: __dxlog_file4,
|
|
1128
|
-
L: 324,
|
|
1129
|
-
S: this,
|
|
1130
|
-
A: [
|
|
1131
|
-
"convergedPaths.length >= 1",
|
|
1132
|
-
""
|
|
1133
|
-
]
|
|
1134
|
-
});
|
|
1051
|
+
invariant4(convergedPaths.length >= 1, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 320, S: this, A: ["convergedPaths.length >= 1", ""] });
|
|
1135
1052
|
if (convergedPaths.length === 1) {
|
|
1136
1053
|
return {
|
|
1137
1054
|
type: "merged",
|
|
@@ -1143,22 +1060,9 @@ var CredentialGraph = class {
|
|
|
1143
1060
|
forkPointId: forkPoint.head.id,
|
|
1144
1061
|
pathCount: convergedPaths.length,
|
|
1145
1062
|
forkPoints: convergedPaths.map((fp) => fp.forkPoint?.head.id)
|
|
1146
|
-
}), {
|
|
1147
|
-
F: __dxlog_file4,
|
|
1148
|
-
L: 329,
|
|
1149
|
-
S: this,
|
|
1150
|
-
C: (f, a) => f(...a)
|
|
1151
|
-
});
|
|
1063
|
+
}), { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 328, S: this });
|
|
1152
1064
|
const paths = convergedPaths.map((p) => this._moveUpToForkPoint(forkPoint, p));
|
|
1153
|
-
invariant4(forkPoint, void 0, {
|
|
1154
|
-
F: __dxlog_file4,
|
|
1155
|
-
L: 335,
|
|
1156
|
-
S: this,
|
|
1157
|
-
A: [
|
|
1158
|
-
"forkPoint",
|
|
1159
|
-
""
|
|
1160
|
-
]
|
|
1161
|
-
});
|
|
1065
|
+
invariant4(forkPoint, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 334, S: this, A: ["forkPoint", ""] });
|
|
1162
1066
|
const result = {
|
|
1163
1067
|
forkPoint: forkPoint.forkPoint,
|
|
1164
1068
|
chosenPath: {
|
|
@@ -1179,12 +1083,7 @@ var CredentialGraph = class {
|
|
|
1179
1083
|
modified: path.forkChangedSubjects,
|
|
1180
1084
|
forkIssuers: path.forkIssuers,
|
|
1181
1085
|
state: path.state.mapValues((v) => this._stateHandler.toLogString(v.assertion))
|
|
1182
|
-
}), {
|
|
1183
|
-
F: __dxlog_file4,
|
|
1184
|
-
L: 348,
|
|
1185
|
-
S: this,
|
|
1186
|
-
C: (f, a) => f(...a)
|
|
1187
|
-
});
|
|
1086
|
+
}), { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 350, S: this });
|
|
1188
1087
|
path.forkIssuers.forEach((iss) => result.forkIssuers.add(iss));
|
|
1189
1088
|
path.credentials.forEach((cred) => result.credentials.add(cred));
|
|
1190
1089
|
result.chosenPath[forkPoint.head.id].push(...path.chosenPath[forkPoint.head.id] ?? []);
|
|
@@ -1204,12 +1103,7 @@ var CredentialGraph = class {
|
|
|
1204
1103
|
log("set subject state", () => ({
|
|
1205
1104
|
subject,
|
|
1206
1105
|
state: this._stateHandler.toLogString(vertex.assertion)
|
|
1207
|
-
}), {
|
|
1208
|
-
F: __dxlog_file4,
|
|
1209
|
-
L: 370,
|
|
1210
|
-
S: this,
|
|
1211
|
-
C: (f, a) => f(...a)
|
|
1212
|
-
});
|
|
1106
|
+
}), { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 372, S: this });
|
|
1213
1107
|
const otherPaths = paths.filter((p) => p !== branch);
|
|
1214
1108
|
this._stateHandler.getConflictingPaths(otherPaths, vertex).forEach(addReplayPath);
|
|
1215
1109
|
}
|
|
@@ -1248,12 +1142,7 @@ var CredentialGraph = class {
|
|
|
1248
1142
|
if (candidateVertex.id === mergePointId || currentVertex.id === mergePointId) {
|
|
1249
1143
|
log("merge point chosen to break the tie", {
|
|
1250
1144
|
mergePointId: existing.head.id
|
|
1251
|
-
}, {
|
|
1252
|
-
F: __dxlog_file4,
|
|
1253
|
-
L: 408,
|
|
1254
|
-
S: this,
|
|
1255
|
-
C: (f, a) => f(...a)
|
|
1256
|
-
});
|
|
1145
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 412, S: this });
|
|
1257
1146
|
return mergePointId === candidateVertex.id;
|
|
1258
1147
|
}
|
|
1259
1148
|
const candidateCredential = candidateVertex.credential;
|
|
@@ -1262,12 +1151,7 @@ var CredentialGraph = class {
|
|
|
1262
1151
|
log("one of the credentials was overridden in another branch", {
|
|
1263
1152
|
current: currentVertex.id,
|
|
1264
1153
|
candidate: candidateVertex.id
|
|
1265
|
-
}, {
|
|
1266
|
-
F: __dxlog_file4,
|
|
1267
|
-
L: 415,
|
|
1268
|
-
S: this,
|
|
1269
|
-
C: (f, a) => f(...a)
|
|
1270
|
-
});
|
|
1154
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 421, S: this });
|
|
1271
1155
|
return candidate.credentials.has(currentCredential.id);
|
|
1272
1156
|
}
|
|
1273
1157
|
const winningCredential = this._stateHandler.tryPickWinningUpdate(existing, currentCredential, candidate, candidateCredential);
|
|
@@ -1280,20 +1164,10 @@ var CredentialGraph = class {
|
|
|
1280
1164
|
existing.forkIssuers.size,
|
|
1281
1165
|
candidate.forkIssuers.size
|
|
1282
1166
|
]
|
|
1283
|
-
}, {
|
|
1284
|
-
F: __dxlog_file4,
|
|
1285
|
-
L: 432,
|
|
1286
|
-
S: this,
|
|
1287
|
-
C: (f, a) => f(...a)
|
|
1288
|
-
});
|
|
1167
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 433, S: this });
|
|
1289
1168
|
return candidate.forkIssuers.size > existing.forkIssuers.size;
|
|
1290
1169
|
}
|
|
1291
|
-
log("issuance date used to break the tie", void 0, {
|
|
1292
|
-
F: __dxlog_file4,
|
|
1293
|
-
L: 437,
|
|
1294
|
-
S: this,
|
|
1295
|
-
C: (f, a) => f(...a)
|
|
1296
|
-
});
|
|
1170
|
+
log("issuance date used to break the tie", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 441, S: this });
|
|
1297
1171
|
return candidateCredential.issuanceDate.getTime() > currentCredential.issuanceDate.getTime();
|
|
1298
1172
|
}
|
|
1299
1173
|
_createRootPath() {
|
|
@@ -1314,14 +1188,16 @@ var toChosenPath = (path) => {
|
|
|
1314
1188
|
]));
|
|
1315
1189
|
};
|
|
1316
1190
|
|
|
1317
|
-
//
|
|
1318
|
-
var __dxlog_file5 = "/
|
|
1191
|
+
// src/state-machine/member-state-machine.ts
|
|
1192
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/halo/credentials/src/state-machine/member-state-machine.ts";
|
|
1319
1193
|
var MemberStateMachine = class {
|
|
1194
|
+
_spaceKey;
|
|
1195
|
+
_ownerKey;
|
|
1196
|
+
_memberProfiles = new ComplexMap5(PublicKey7.hash);
|
|
1197
|
+
_hashgraph = new CredentialGraph(this);
|
|
1198
|
+
onMemberRoleChanged = this._hashgraph.onSubjectStateChanged;
|
|
1320
1199
|
constructor(_spaceKey) {
|
|
1321
1200
|
this._spaceKey = _spaceKey;
|
|
1322
|
-
this._memberProfiles = new ComplexMap5(PublicKey7.hash);
|
|
1323
|
-
this._hashgraph = new CredentialGraph(this);
|
|
1324
|
-
this.onMemberRoleChanged = this._hashgraph.onSubjectStateChanged;
|
|
1325
1201
|
}
|
|
1326
1202
|
get creator() {
|
|
1327
1203
|
return this._ownerKey && this._hashgraph.getSubjectState(this._ownerKey);
|
|
@@ -1343,15 +1219,7 @@ var MemberStateMachine = class {
|
|
|
1343
1219
|
const assertion = getCredentialAssertion(credential);
|
|
1344
1220
|
switch (assertion["@type"]) {
|
|
1345
1221
|
case "dxos.halo.credentials.SpaceMember": {
|
|
1346
|
-
invariant5(assertion.spaceKey.equals(this._spaceKey), void 0, {
|
|
1347
|
-
F: __dxlog_file5,
|
|
1348
|
-
L: 66,
|
|
1349
|
-
S: this,
|
|
1350
|
-
A: [
|
|
1351
|
-
"assertion.spaceKey.equals(this._spaceKey)",
|
|
1352
|
-
""
|
|
1353
|
-
]
|
|
1354
|
-
});
|
|
1222
|
+
invariant5(assertion.spaceKey.equals(this._spaceKey), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 43, S: this, A: ["assertion.spaceKey.equals(this._spaceKey)", ""] });
|
|
1355
1223
|
if (this._ownerKey == null && credential.issuer === this._spaceKey) {
|
|
1356
1224
|
this._ownerKey = credential.subject.id;
|
|
1357
1225
|
}
|
|
@@ -1368,12 +1236,7 @@ var MemberStateMachine = class {
|
|
|
1368
1236
|
} else {
|
|
1369
1237
|
log2.warn("Member not found", {
|
|
1370
1238
|
id: credential.subject.id
|
|
1371
|
-
}, {
|
|
1372
|
-
F: __dxlog_file5,
|
|
1373
|
-
L: 81,
|
|
1374
|
-
S: this,
|
|
1375
|
-
C: (f, a) => f(...a)
|
|
1376
|
-
});
|
|
1239
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 59, S: this });
|
|
1377
1240
|
}
|
|
1378
1241
|
this._memberProfiles.set(credential.subject.id, assertion.profile);
|
|
1379
1242
|
break;
|
|
@@ -1418,12 +1281,7 @@ var MemberStateMachine = class {
|
|
|
1418
1281
|
const path1IssuerRole = this._getRole(scope1, update1.issuer);
|
|
1419
1282
|
const path2IssuerRole = this._getRole(scope2, update2.issuer);
|
|
1420
1283
|
if (path2IssuerRole === SpaceMember2.Role.OWNER !== (path1IssuerRole === SpaceMember2.Role.OWNER)) {
|
|
1421
|
-
log2("owner decision used to break the tie", void 0, {
|
|
1422
|
-
F: __dxlog_file5,
|
|
1423
|
-
L: 139,
|
|
1424
|
-
S: this,
|
|
1425
|
-
C: (f, a) => f(...a)
|
|
1426
|
-
});
|
|
1284
|
+
log2("owner decision used to break the tie", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 107, S: this });
|
|
1427
1285
|
return path1IssuerRole === SpaceMember2.Role.OWNER ? update1 : update2;
|
|
1428
1286
|
}
|
|
1429
1287
|
return null;
|
|
@@ -1447,12 +1305,7 @@ var MemberStateMachine = class {
|
|
|
1447
1305
|
headId: scope.head?.id,
|
|
1448
1306
|
roleOverride: this.toLogString(override.assertion),
|
|
1449
1307
|
realRole: this.toLogString(scope.state.get(memberId)?.assertion)
|
|
1450
|
-
}), {
|
|
1451
|
-
F: __dxlog_file5,
|
|
1452
|
-
L: 162,
|
|
1453
|
-
S: this,
|
|
1454
|
-
C: (f, a) => f(...a)
|
|
1455
|
-
});
|
|
1308
|
+
}), { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 127, S: this });
|
|
1456
1309
|
return override.assertion.role;
|
|
1457
1310
|
}
|
|
1458
1311
|
}
|
|
@@ -1460,29 +1313,37 @@ var MemberStateMachine = class {
|
|
|
1460
1313
|
}
|
|
1461
1314
|
};
|
|
1462
1315
|
|
|
1463
|
-
//
|
|
1316
|
+
// src/state-machine/space-state-machine.ts
|
|
1317
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/halo/credentials/src/state-machine/space-state-machine.ts";
|
|
1464
1318
|
function _ts_decorate(decorators, target, key, desc) {
|
|
1465
1319
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1466
1320
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1467
1321
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1468
1322
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1469
1323
|
}
|
|
1470
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/state-machine/space-state-machine.ts";
|
|
1471
1324
|
var SpaceStateMachine = class {
|
|
1325
|
+
_spaceKey;
|
|
1326
|
+
_members;
|
|
1327
|
+
_feeds;
|
|
1328
|
+
_invitations = new InvitationStateMachine();
|
|
1329
|
+
_credentials = [];
|
|
1330
|
+
_credentialsById = new ComplexMap6(PublicKey8.hash);
|
|
1331
|
+
_processedCredentials = new ComplexSet3(PublicKey8.hash);
|
|
1332
|
+
_genesisCredential;
|
|
1333
|
+
_tags = [];
|
|
1334
|
+
_membershipPolicy = MembershipPolicy2.INVITE;
|
|
1335
|
+
_credentialProcessors = [];
|
|
1336
|
+
onCredentialProcessed = new Callback4();
|
|
1337
|
+
onMemberRoleChanged;
|
|
1338
|
+
onFeedAdmitted;
|
|
1339
|
+
onDelegatedInvitation = this._invitations.onDelegatedInvitation;
|
|
1340
|
+
onDelegatedInvitationRemoved = this._invitations.onDelegatedInvitationRemoved;
|
|
1472
1341
|
constructor(_spaceKey) {
|
|
1473
1342
|
this._spaceKey = _spaceKey;
|
|
1474
1343
|
this._members = new MemberStateMachine(this._spaceKey);
|
|
1475
1344
|
this._feeds = new FeedStateMachine(this._spaceKey);
|
|
1476
|
-
this._invitations = new InvitationStateMachine();
|
|
1477
|
-
this._credentials = [];
|
|
1478
|
-
this._credentialsById = new ComplexMap6(PublicKey8.hash);
|
|
1479
|
-
this._processedCredentials = new ComplexSet3(PublicKey8.hash);
|
|
1480
|
-
this._credentialProcessors = [];
|
|
1481
|
-
this.onCredentialProcessed = new Callback4();
|
|
1482
1345
|
this.onMemberRoleChanged = this._members.onMemberRoleChanged;
|
|
1483
1346
|
this.onFeedAdmitted = this._feeds.onFeedAdmitted;
|
|
1484
|
-
this.onDelegatedInvitation = this._invitations.onDelegatedInvitation;
|
|
1485
|
-
this.onDelegatedInvitationRemoved = this._invitations.onDelegatedInvitationRemoved;
|
|
1486
1347
|
}
|
|
1487
1348
|
get creator() {
|
|
1488
1349
|
return this._members.creator;
|
|
@@ -1505,6 +1366,12 @@ var SpaceStateMachine = class {
|
|
|
1505
1366
|
get genesisCredential() {
|
|
1506
1367
|
return this._genesisCredential;
|
|
1507
1368
|
}
|
|
1369
|
+
get tags() {
|
|
1370
|
+
return this._tags;
|
|
1371
|
+
}
|
|
1372
|
+
get membershipPolicy() {
|
|
1373
|
+
return this._membershipPolicy;
|
|
1374
|
+
}
|
|
1508
1375
|
get invitations() {
|
|
1509
1376
|
return this._invitations.invitations;
|
|
1510
1377
|
}
|
|
@@ -1544,12 +1411,7 @@ var SpaceStateMachine = class {
|
|
|
1544
1411
|
if (!skipVerification) {
|
|
1545
1412
|
const result = await verifyCredential(credential);
|
|
1546
1413
|
if (result.kind !== "pass") {
|
|
1547
|
-
log3.warn(`Invalid credential: ${result.errors.join(", ")}`, void 0, {
|
|
1548
|
-
F: __dxlog_file6,
|
|
1549
|
-
L: 156,
|
|
1550
|
-
S: this,
|
|
1551
|
-
C: (f, a) => f(...a)
|
|
1552
|
-
});
|
|
1414
|
+
log3.warn(`Invalid credential: ${result.errors.join(", ")}`, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 116, S: this });
|
|
1553
1415
|
return false;
|
|
1554
1416
|
}
|
|
1555
1417
|
}
|
|
@@ -1557,33 +1419,20 @@ var SpaceStateMachine = class {
|
|
|
1557
1419
|
switch (assertion["@type"]) {
|
|
1558
1420
|
case "dxos.halo.credentials.SpaceGenesis": {
|
|
1559
1421
|
if (this._genesisCredential) {
|
|
1560
|
-
log3.warn("Space already has a genesis credential.", void 0, {
|
|
1561
|
-
F: __dxlog_file6,
|
|
1562
|
-
L: 165,
|
|
1563
|
-
S: this,
|
|
1564
|
-
C: (f, a) => f(...a)
|
|
1565
|
-
});
|
|
1422
|
+
log3.warn("Space already has a genesis credential.", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 125, S: this });
|
|
1566
1423
|
return false;
|
|
1567
1424
|
}
|
|
1568
1425
|
if (!credential.issuer.equals(this._spaceKey)) {
|
|
1569
|
-
log3.warn("Space genesis credential must be issued by space.", void 0, {
|
|
1570
|
-
F: __dxlog_file6,
|
|
1571
|
-
L: 169,
|
|
1572
|
-
S: this,
|
|
1573
|
-
C: (f, a) => f(...a)
|
|
1574
|
-
});
|
|
1426
|
+
log3.warn("Space genesis credential must be issued by space.", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 129, S: this });
|
|
1575
1427
|
return false;
|
|
1576
1428
|
}
|
|
1577
1429
|
if (!credential.subject.id.equals(this._spaceKey)) {
|
|
1578
|
-
log3.warn("Space genesis credential must be issued to space.", void 0, {
|
|
1579
|
-
F: __dxlog_file6,
|
|
1580
|
-
L: 173,
|
|
1581
|
-
S: this,
|
|
1582
|
-
C: (f, a) => f(...a)
|
|
1583
|
-
});
|
|
1430
|
+
log3.warn("Space genesis credential must be issued to space.", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 133, S: this });
|
|
1584
1431
|
return false;
|
|
1585
1432
|
}
|
|
1586
1433
|
this._genesisCredential = credential;
|
|
1434
|
+
this._tags = assertion.tags ?? [];
|
|
1435
|
+
this._membershipPolicy = assertion.membershipPolicy ?? MembershipPolicy2.INVITE;
|
|
1587
1436
|
break;
|
|
1588
1437
|
}
|
|
1589
1438
|
case "dxos.halo.credentials.SpaceMember": {
|
|
@@ -1591,21 +1440,11 @@ var SpaceStateMachine = class {
|
|
|
1591
1440
|
break;
|
|
1592
1441
|
}
|
|
1593
1442
|
if (!this._genesisCredential) {
|
|
1594
|
-
log3.warn("Space must have a genesis credential before adding members.", void 0, {
|
|
1595
|
-
F: __dxlog_file6,
|
|
1596
|
-
L: 186,
|
|
1597
|
-
S: this,
|
|
1598
|
-
C: (f, a) => f(...a)
|
|
1599
|
-
});
|
|
1443
|
+
log3.warn("Space must have a genesis credential before adding members.", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 147, S: this });
|
|
1600
1444
|
return false;
|
|
1601
1445
|
}
|
|
1602
1446
|
if (!this._canInviteNewMembers(credential.issuer)) {
|
|
1603
|
-
log3.warn(`Space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
|
|
1604
|
-
F: __dxlog_file6,
|
|
1605
|
-
L: 190,
|
|
1606
|
-
S: this,
|
|
1607
|
-
C: (f, a) => f(...a)
|
|
1608
|
-
});
|
|
1447
|
+
log3.warn(`Space member is not authorized to invite new members: ${credential.issuer}`, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 151, S: this });
|
|
1609
1448
|
return false;
|
|
1610
1449
|
}
|
|
1611
1450
|
await this._members.process(credential);
|
|
@@ -1614,12 +1453,7 @@ var SpaceStateMachine = class {
|
|
|
1614
1453
|
}
|
|
1615
1454
|
case "dxos.halo.credentials.MemberProfile": {
|
|
1616
1455
|
if (!this._genesisCredential) {
|
|
1617
|
-
log3.warn("Space must have a genesis credential before adding members.", void 0, {
|
|
1618
|
-
F: __dxlog_file6,
|
|
1619
|
-
L: 201,
|
|
1620
|
-
S: this,
|
|
1621
|
-
C: (f, a) => f(...a)
|
|
1622
|
-
});
|
|
1456
|
+
log3.warn("Space must have a genesis credential before adding members.", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 161, S: this });
|
|
1623
1457
|
return false;
|
|
1624
1458
|
}
|
|
1625
1459
|
await this._members.process(credential);
|
|
@@ -1627,12 +1461,7 @@ var SpaceStateMachine = class {
|
|
|
1627
1461
|
}
|
|
1628
1462
|
case "dxos.halo.credentials.AdmittedFeed": {
|
|
1629
1463
|
if (!this._genesisCredential) {
|
|
1630
|
-
log3.warn("Space must have a genesis credential before admitting feeds.", void 0, {
|
|
1631
|
-
F: __dxlog_file6,
|
|
1632
|
-
L: 211,
|
|
1633
|
-
S: this,
|
|
1634
|
-
C: (f, a) => f(...a)
|
|
1635
|
-
});
|
|
1464
|
+
log3.warn("Space must have a genesis credential before admitting feeds.", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 170, S: this });
|
|
1636
1465
|
return false;
|
|
1637
1466
|
}
|
|
1638
1467
|
await this._feeds.process(credential, sourceFeed);
|
|
@@ -1641,12 +1470,7 @@ var SpaceStateMachine = class {
|
|
|
1641
1470
|
case "dxos.halo.invitations.CancelDelegatedInvitation":
|
|
1642
1471
|
case "dxos.halo.invitations.DelegateSpaceInvitation": {
|
|
1643
1472
|
if (!this._canInviteNewMembers(credential.issuer)) {
|
|
1644
|
-
log3.warn(`Invalid invitation, space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
|
|
1645
|
-
F: __dxlog_file6,
|
|
1646
|
-
L: 222,
|
|
1647
|
-
S: this,
|
|
1648
|
-
C: (f, a) => f(...a)
|
|
1649
|
-
});
|
|
1473
|
+
log3.warn(`Invalid invitation, space member is not authorized to invite new members: ${credential.issuer}`, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 181, S: this });
|
|
1650
1474
|
return false;
|
|
1651
1475
|
}
|
|
1652
1476
|
await this._invitations.process(credential);
|
|
@@ -1677,6 +1501,9 @@ var SpaceStateMachine = class {
|
|
|
1677
1501
|
return this._canInviteNewMembers(memberKey);
|
|
1678
1502
|
}
|
|
1679
1503
|
_canInviteNewMembers(key) {
|
|
1504
|
+
if (this._membershipPolicy === MembershipPolicy2.LOCKED) {
|
|
1505
|
+
return key.equals(this._spaceKey) && this._members.members.size === 0;
|
|
1506
|
+
}
|
|
1680
1507
|
return key.equals(this._spaceKey) || this._members.getRole(key) === SpaceMember3.Role.ADMIN || this._members.getRole(key) === SpaceMember3.Role.OWNER;
|
|
1681
1508
|
}
|
|
1682
1509
|
};
|
|
@@ -1684,15 +1511,21 @@ _ts_decorate([
|
|
|
1684
1511
|
synchronized
|
|
1685
1512
|
], SpaceStateMachine.prototype, "process", null);
|
|
1686
1513
|
var CredentialConsumer = class {
|
|
1514
|
+
processor;
|
|
1515
|
+
_onOpen;
|
|
1516
|
+
_onClose;
|
|
1517
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 229 });
|
|
1518
|
+
/**
|
|
1519
|
+
* @internal
|
|
1520
|
+
* Processor is ready to process live credentials.
|
|
1521
|
+
* NOTE: Setting this flag before all existing credentials are processed will cause them to be processed out of order.
|
|
1522
|
+
* Set externally.
|
|
1523
|
+
*/
|
|
1524
|
+
_isReadyForLiveCredentials = false;
|
|
1687
1525
|
constructor(processor, _onOpen, _onClose) {
|
|
1688
1526
|
this.processor = processor;
|
|
1689
1527
|
this._onOpen = _onOpen;
|
|
1690
1528
|
this._onClose = _onClose;
|
|
1691
|
-
this._ctx = new Context(void 0, {
|
|
1692
|
-
F: __dxlog_file6,
|
|
1693
|
-
L: 267
|
|
1694
|
-
});
|
|
1695
|
-
this._isReadyForLiveCredentials = false;
|
|
1696
1529
|
}
|
|
1697
1530
|
/**
|
|
1698
1531
|
* @internal
|
|
@@ -1714,30 +1547,28 @@ var CredentialConsumer = class {
|
|
|
1714
1547
|
}
|
|
1715
1548
|
};
|
|
1716
1549
|
|
|
1717
|
-
//
|
|
1550
|
+
// src/processor/device-state-machine.ts
|
|
1718
1551
|
import { Trigger } from "@dxos/async";
|
|
1719
1552
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
1720
1553
|
import { PublicKey as PublicKey9 } from "@dxos/keys";
|
|
1721
1554
|
import { log as log4 } from "@dxos/log";
|
|
1722
1555
|
import { ComplexMap as ComplexMap7 } from "@dxos/util";
|
|
1723
|
-
var __dxlog_file7 = "/
|
|
1556
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/halo/credentials/src/processor/device-state-machine.ts";
|
|
1724
1557
|
var DeviceStateMachine = class {
|
|
1558
|
+
_params;
|
|
1559
|
+
// TODO(burdon): Return values via getter.
|
|
1560
|
+
authorizedDeviceKeys = new ComplexMap7(PublicKey9.hash);
|
|
1561
|
+
deviceChainReady = new Trigger();
|
|
1562
|
+
deviceCredentialChain;
|
|
1725
1563
|
constructor(_params) {
|
|
1726
1564
|
this._params = _params;
|
|
1727
|
-
this.authorizedDeviceKeys = new ComplexMap7(PublicKey9.hash);
|
|
1728
|
-
this.deviceChainReady = new Trigger();
|
|
1729
1565
|
}
|
|
1730
1566
|
async processCredential(credential) {
|
|
1731
1567
|
log4("processing credential...", {
|
|
1732
1568
|
identityKey: this._params.identityKey,
|
|
1733
1569
|
deviceKey: this._params.deviceKey,
|
|
1734
1570
|
credential
|
|
1735
|
-
}, {
|
|
1736
|
-
F: __dxlog_file7,
|
|
1737
|
-
L: 35,
|
|
1738
|
-
S: this,
|
|
1739
|
-
C: (f, a) => f(...a)
|
|
1740
|
-
});
|
|
1571
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 22, S: this });
|
|
1741
1572
|
if (isValidAuthorizedDeviceCredential(credential, this._params.identityKey, this._params.deviceKey)) {
|
|
1742
1573
|
this.deviceCredentialChain = {
|
|
1743
1574
|
credential
|
|
@@ -1752,35 +1583,17 @@ var DeviceStateMachine = class {
|
|
|
1752
1583
|
localDeviceKey: this._params.deviceKey,
|
|
1753
1584
|
deviceKey: assertion.deviceKey,
|
|
1754
1585
|
size: this.authorizedDeviceKeys.size
|
|
1755
|
-
}, {
|
|
1756
|
-
F: __dxlog_file7,
|
|
1757
|
-
L: 55,
|
|
1758
|
-
S: this,
|
|
1759
|
-
C: (f, a) => f(...a)
|
|
1760
|
-
});
|
|
1586
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 41, S: this });
|
|
1761
1587
|
this._params.onUpdate?.();
|
|
1762
1588
|
break;
|
|
1763
1589
|
}
|
|
1764
1590
|
case "dxos.halo.credentials.DeviceProfile": {
|
|
1765
|
-
invariant6(this.authorizedDeviceKeys.has(credential.subject.id), "Device not found.", {
|
|
1766
|
-
F: __dxlog_file7,
|
|
1767
|
-
L: 65,
|
|
1768
|
-
S: this,
|
|
1769
|
-
A: [
|
|
1770
|
-
"this.authorizedDeviceKeys.has(credential.subject.id)",
|
|
1771
|
-
"'Device not found.'"
|
|
1772
|
-
]
|
|
1773
|
-
});
|
|
1591
|
+
invariant6(this.authorizedDeviceKeys.has(credential.subject.id), "Device not found.", { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 51, S: this, A: ["this.authorizedDeviceKeys.has(credential.subject.id)", "'Device not found.'"] });
|
|
1774
1592
|
if (assertion && credential.subject.id.equals(this._params.deviceKey)) {
|
|
1775
1593
|
log4.trace("dxos.halo.device", {
|
|
1776
1594
|
deviceKey: credential.subject.id,
|
|
1777
1595
|
profile: assertion.profile
|
|
1778
|
-
}, {
|
|
1779
|
-
F: __dxlog_file7,
|
|
1780
|
-
L: 68,
|
|
1781
|
-
S: this,
|
|
1782
|
-
C: (f, a) => f(...a)
|
|
1783
|
-
});
|
|
1596
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 53, S: this });
|
|
1784
1597
|
}
|
|
1785
1598
|
this.authorizedDeviceKeys.set(credential.subject.id, assertion.profile);
|
|
1786
1599
|
this._params.onUpdate?.();
|
|
@@ -1790,10 +1603,13 @@ var DeviceStateMachine = class {
|
|
|
1790
1603
|
}
|
|
1791
1604
|
};
|
|
1792
1605
|
|
|
1793
|
-
//
|
|
1606
|
+
// src/processor/profile-state-machine.ts
|
|
1794
1607
|
import { log as log5 } from "@dxos/log";
|
|
1795
|
-
var __dxlog_file8 = "/
|
|
1608
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/halo/credentials/src/processor/profile-state-machine.ts";
|
|
1796
1609
|
var ProfileStateMachine = class {
|
|
1610
|
+
_params;
|
|
1611
|
+
// TODO(burdon): Return values via getter.
|
|
1612
|
+
profile;
|
|
1797
1613
|
constructor(_params) {
|
|
1798
1614
|
this._params = _params;
|
|
1799
1615
|
}
|
|
@@ -1805,24 +1621,14 @@ var ProfileStateMachine = class {
|
|
|
1805
1621
|
log5.warn("Invalid profile credential", {
|
|
1806
1622
|
expectedIdentity: this._params.identityKey,
|
|
1807
1623
|
credential
|
|
1808
|
-
}, {
|
|
1809
|
-
F: __dxlog_file8,
|
|
1810
|
-
L: 34,
|
|
1811
|
-
S: this,
|
|
1812
|
-
C: (f, a) => f(...a)
|
|
1813
|
-
});
|
|
1624
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 21, S: this });
|
|
1814
1625
|
return;
|
|
1815
1626
|
}
|
|
1816
1627
|
this.profile = assertion.profile;
|
|
1817
1628
|
log5("updated profile", {
|
|
1818
1629
|
identityKey: this._params.identityKey,
|
|
1819
1630
|
profile: this.profile
|
|
1820
|
-
}, {
|
|
1821
|
-
F: __dxlog_file8,
|
|
1822
|
-
L: 40,
|
|
1823
|
-
S: this,
|
|
1824
|
-
C: (f, a) => f(...a)
|
|
1825
|
-
});
|
|
1631
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 29, S: this });
|
|
1826
1632
|
this._params.onUpdate?.();
|
|
1827
1633
|
break;
|
|
1828
1634
|
}
|