@dxos/credentials 0.8.3 → 0.8.4-main.28f8d3d

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.
Files changed (47) hide show
  1. package/.swc/plugins/v7_linux_x86_64_13.0.0/c614d7475354583212fbd7669acbae95b9832c305bf51bdaabe2e6de05abb6bf +0 -0
  2. package/dist/lib/browser/index.mjs +124 -58
  3. package/dist/lib/browser/index.mjs.map +3 -3
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +124 -58
  6. package/dist/lib/node-esm/index.mjs.map +3 -3
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/credentials/assertions.d.ts +1 -1
  9. package/dist/types/src/credentials/assertions.d.ts.map +1 -1
  10. package/dist/types/src/credentials/credential-generator.d.ts.map +1 -1
  11. package/dist/types/src/did.d.ts +1 -1
  12. package/dist/types/src/did.d.ts.map +1 -1
  13. package/dist/types/src/presentations/presentation.d.ts.map +1 -1
  14. package/dist/types/src/presentations/verifier.d.ts.map +1 -1
  15. package/dist/types/src/processor/device-state-machine.d.ts.map +1 -1
  16. package/dist/types/src/processor/index.d.ts +1 -1
  17. package/dist/types/src/processor/index.d.ts.map +1 -1
  18. package/dist/types/src/processor/profile-state-machine.d.ts.map +1 -1
  19. package/dist/types/src/state-machine/member-state-machine.d.ts +1 -1
  20. package/dist/types/src/state-machine/member-state-machine.d.ts.map +1 -1
  21. package/dist/types/src/state-machine/space-state-machine.d.ts +1 -1
  22. package/dist/types/src/state-machine/space-state-machine.d.ts.map +1 -1
  23. package/dist/types/tsconfig.tsbuildinfo +1 -1
  24. package/moon.yml +11 -0
  25. package/package.json +13 -12
  26. package/src/credentials/assertions.ts +1 -1
  27. package/src/credentials/credential-factory.ts +1 -1
  28. package/src/credentials/credential-generator.ts +1 -1
  29. package/src/did.ts +2 -2
  30. package/src/presentations/json-encoding.test.ts +3 -1
  31. package/src/presentations/presentation.ts +2 -1
  32. package/src/presentations/verifier.test.ts +2 -1
  33. package/src/presentations/verifier.ts +2 -1
  34. package/src/processor/device-state-machine.ts +2 -1
  35. package/src/processor/index.ts +1 -1
  36. package/src/processor/profile-state-machine.ts +2 -1
  37. package/src/state-machine/invitation-state-machine.test.ts +3 -2
  38. package/src/state-machine/member-state-machine.test.ts +2 -1
  39. package/src/state-machine/member-state-machine.ts +1 -1
  40. package/src/state-machine/space-state-machine.test.ts +2 -1
  41. package/src/state-machine/space-state-machine.ts +14 -8
  42. package/vitest.config.ts +5 -2
  43. package/.eslintrc.cjs +0 -7
  44. package/dist/lib/node/index.cjs +0 -1894
  45. package/dist/lib/node/index.cjs.map +0 -7
  46. package/dist/lib/node/meta.json +0 -1
  47. package/project.json +0 -27
@@ -1,1894 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var node_exports = {};
30
- __export(node_exports, {
31
- CredentialGenerator: () => CredentialGenerator,
32
- DeviceStateMachine: () => DeviceStateMachine,
33
- FeedStateMachine: () => FeedStateMachine,
34
- InvitationStateMachine: () => InvitationStateMachine,
35
- MemberStateMachine: () => MemberStateMachine,
36
- ProfileStateMachine: () => ProfileStateMachine,
37
- SIGNATURE_TYPE_ED25519: () => SIGNATURE_TYPE_ED25519,
38
- SpaceStateMachine: () => SpaceStateMachine,
39
- canonicalStringify: () => canonicalStringify,
40
- checkCredentialType: () => checkCredentialType,
41
- createAdmissionCredentials: () => createAdmissionCredentials,
42
- createCancelDelegatedSpaceInvitationCredential: () => createCancelDelegatedSpaceInvitationCredential,
43
- createCredential: () => createCredential,
44
- createCredentialMessage: () => createCredentialMessage,
45
- createCredentialSignerWithChain: () => createCredentialSignerWithChain,
46
- createCredentialSignerWithKey: () => createCredentialSignerWithKey,
47
- createDelegatedSpaceInvitationCredential: () => createDelegatedSpaceInvitationCredential,
48
- createDeviceAuthorization: () => createDeviceAuthorization,
49
- createDidFromIdentityKey: () => createDidFromIdentityKey,
50
- credentialTypeFilter: () => credentialTypeFilter,
51
- defaultSecretProvider: () => defaultSecretProvider,
52
- defaultSecretValidator: () => defaultSecretValidator,
53
- generatePasscode: () => generatePasscode,
54
- generateSeedPhrase: () => generateSeedPhrase,
55
- getCredentialAssertion: () => getCredentialAssertion,
56
- getCredentialProofPayload: () => getCredentialProofPayload,
57
- getPresentationProofPayload: () => getPresentationProofPayload,
58
- isValidAuthorizedDeviceCredential: () => isValidAuthorizedDeviceCredential,
59
- keyPairFromSeedPhrase: () => keyPairFromSeedPhrase,
60
- signPresentation: () => signPresentation,
61
- verifyChain: () => verifyChain,
62
- verifyCredential: () => verifyCredential,
63
- verifyCredentialSignature: () => verifyCredentialSignature,
64
- verifyPresentation: () => verifyPresentation,
65
- verifyPresentationChain: () => verifyPresentationChain,
66
- verifyPresentationSignature: () => verifyPresentationSignature
67
- });
68
- module.exports = __toCommonJS(node_exports);
69
- var import_crypto = require("@dxos/crypto");
70
- var import_keys = require("@dxos/keys");
71
- var import_util = require("@dxos/util");
72
- var import_bip39 = require("bip39");
73
- var import_crypto2 = require("@dxos/crypto");
74
- var import_invariant = require("@dxos/invariant");
75
- var import_json_stable_stringify = __toESM(require("json-stable-stringify"));
76
- var import_keys2 = require("@dxos/keys");
77
- var import_timeframe = require("@dxos/timeframe");
78
- var import_util2 = require("@dxos/util");
79
- var import_crypto3 = require("@dxos/crypto");
80
- var import_invariant2 = require("@dxos/invariant");
81
- var import_keys3 = require("@dxos/keys");
82
- var import_crypto4 = require("@dxos/crypto");
83
- var import_credentials = require("@dxos/protocols/proto/dxos/halo/credentials");
84
- var import_timeframe2 = require("@dxos/timeframe");
85
- var import_crypto5 = require("@dxos/crypto");
86
- var import_async = require("@dxos/async");
87
- var import_context = require("@dxos/context");
88
- var import_keys4 = require("@dxos/keys");
89
- var import_log = require("@dxos/log");
90
- var import_credentials2 = require("@dxos/protocols/proto/dxos/halo/credentials");
91
- var import_util3 = require("@dxos/util");
92
- var import_invariant3 = require("@dxos/invariant");
93
- var import_keys5 = require("@dxos/keys");
94
- var import_util4 = require("@dxos/util");
95
- var import_keys6 = require("@dxos/keys");
96
- var import_util5 = require("@dxos/util");
97
- var import_invariant4 = require("@dxos/invariant");
98
- var import_keys7 = require("@dxos/keys");
99
- var import_log2 = require("@dxos/log");
100
- var import_credentials3 = require("@dxos/protocols/proto/dxos/halo/credentials");
101
- var import_util6 = require("@dxos/util");
102
- var import_invariant5 = require("@dxos/invariant");
103
- var import_keys8 = require("@dxos/keys");
104
- var import_log3 = require("@dxos/log");
105
- var import_util7 = require("@dxos/util");
106
- var import_async2 = require("@dxos/async");
107
- var import_invariant6 = require("@dxos/invariant");
108
- var import_keys9 = require("@dxos/keys");
109
- var import_log4 = require("@dxos/log");
110
- var import_util8 = require("@dxos/util");
111
- var import_log5 = require("@dxos/log");
112
- var IDENTITY_DIDS_CACHE = new import_util.ComplexMap(import_keys.PublicKey.hash);
113
- var createDidFromIdentityKey = async (identityKey) => {
114
- const cachedValue = IDENTITY_DIDS_CACHE.get(identityKey);
115
- if (cachedValue !== void 0) {
116
- return cachedValue;
117
- }
118
- const digest = await import_crypto.subtleCrypto.digest("SHA-256", identityKey.asUint8Array());
119
- const bytes = new Uint8Array(digest).slice(0, import_keys.IdentityDid.byteLength);
120
- const identityDid = import_keys.IdentityDid.encode(bytes);
121
- IDENTITY_DIDS_CACHE.set(identityKey, identityDid);
122
- return identityDid;
123
- };
124
- var defaultSecretProvider = async () => Buffer.from("0000");
125
- var defaultSecretValidator = async (invitation, secret) => true;
126
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/seedphrase.ts";
127
- var generateSeedPhrase = () => (0, import_bip39.generateMnemonic)();
128
- var keyPairFromSeedPhrase = (seedPhrase) => {
129
- (0, import_invariant.invariant)(seedPhrase, void 0, {
130
- F: __dxlog_file,
131
- L: 20,
132
- S: void 0,
133
- A: [
134
- "seedPhrase",
135
- ""
136
- ]
137
- });
138
- const seed = (0, import_bip39.mnemonicToSeedSync)(seedPhrase);
139
- return (0, import_crypto2.createKeyPair)(seed);
140
- };
141
- var generatePasscode = (length = 4) => {
142
- let passcode = "";
143
- for (let i = 0; i < length; i++) {
144
- passcode += `${Math.floor(Math.random() * 10)}`;
145
- }
146
- return passcode;
147
- };
148
- var getCredentialProofPayload = (credential) => {
149
- const copy = {
150
- ...credential,
151
- proof: {
152
- ...credential.proof,
153
- value: new Uint8Array(),
154
- chain: void 0
155
- }
156
- };
157
- if (copy.parentCredentialIds?.length === 0) {
158
- delete copy.parentCredentialIds;
159
- }
160
- delete copy.id;
161
- return Buffer.from(canonicalStringify(copy));
162
- };
163
- var canonicalStringify = (obj) => (0, import_json_stable_stringify.default)(obj, {
164
- /* The point of signing and verifying is not that the internal, private state of the objects be
165
- * identical, but that the public contents can be verified not to have been altered. For that reason,
166
- * really private fields (indicated by '__') are not included in the signature.
167
- * This gives a mechanism for attaching other attributes to an object without breaking the signature.
168
- * We also skip @type.
169
- */
170
- // TODO(dmaretskyi): Should we actually skip the @type field?
171
- replacer: function(key, value) {
172
- if (key.toString().startsWith("__") || key.toString() === "@type") {
173
- return void 0;
174
- }
175
- if (value === null) {
176
- return void 0;
177
- }
178
- const original = this[key];
179
- if (value) {
180
- if (import_keys2.PublicKey.isPublicKey(value)) {
181
- return value.toHex();
182
- }
183
- if (Buffer.isBuffer(value)) {
184
- return value.toString("hex");
185
- }
186
- if (value instanceof Uint8Array) {
187
- return (0, import_util2.arrayToBuffer)(value).toString("hex");
188
- }
189
- if (value.data && value.type === "Buffer") {
190
- return Buffer.from(value).toString("hex");
191
- }
192
- if (original instanceof import_timeframe.Timeframe) {
193
- return original.frames().reduce((frames, [key2, seq]) => {
194
- frames[truncateKey(key2)] = seq;
195
- return frames;
196
- }, {});
197
- }
198
- }
199
- return value;
200
- }
201
- });
202
- var truncateKey = (key) => {
203
- const str = key.toHex();
204
- return `${str.substring(0, 4)}...${str.substring(str.length - 4)}`;
205
- };
206
- var getPresentationProofPayload = (credentials, proof) => {
207
- const copy = {
208
- credentials: credentials.map((credential) => removeEmptyParentCredentialIds(credential)),
209
- proof: {
210
- ...proof,
211
- value: new Uint8Array(),
212
- chain: void 0
213
- }
214
- };
215
- return Buffer.from(canonicalStringify(copy));
216
- };
217
- var removeEmptyParentCredentialIds = (credential) => {
218
- const copy = {
219
- ...credential,
220
- proof: credential.proof ? {
221
- ...credential.proof,
222
- chain: credential.proof.chain ? {
223
- credential: removeEmptyParentCredentialIds(credential.proof.chain.credential)
224
- } : void 0
225
- } : void 0
226
- };
227
- if (copy.parentCredentialIds?.length === 0) {
228
- delete copy.parentCredentialIds;
229
- }
230
- return copy;
231
- };
232
- var getCredentialAssertion = (credential) => credential.subject.assertion;
233
- var isValidAuthorizedDeviceCredential = (credential, identityKey, deviceKey) => {
234
- const assertion = getCredentialAssertion(credential);
235
- return credential.subject.id.equals(deviceKey) && credential.issuer.equals(identityKey) && assertion["@type"] === "dxos.halo.credentials.AuthorizedDevice" && assertion.identityKey.equals(identityKey) && assertion.deviceKey.equals(deviceKey);
236
- };
237
- var checkCredentialType = (credential, type) => credential.subject.assertion["@type"] === type;
238
- var credentialTypeFilter = (type) => (credential) => checkCredentialType(credential, type);
239
- var SIGNATURE_TYPE_ED25519 = "ED25519Signature";
240
- var verifyCredential = async (credential) => {
241
- if (credential.parentCredentialIds?.length === 0) {
242
- delete credential.parentCredentialIds;
243
- }
244
- if (!credential.issuer.equals(credential.proof.signer)) {
245
- if (!credential.proof.chain) {
246
- return {
247
- kind: "fail",
248
- errors: [
249
- "Delegated credential is missing credential chain."
250
- ]
251
- };
252
- }
253
- const result2 = await verifyChain(credential.proof.chain, credential.issuer, credential.proof.signer);
254
- if (result2.kind === "fail") {
255
- return result2;
256
- }
257
- }
258
- const result = await verifyCredentialSignature(credential);
259
- if (result.kind === "fail") {
260
- return result;
261
- }
262
- return {
263
- kind: "pass"
264
- };
265
- };
266
- var verifyCredentialSignature = async (credential) => {
267
- if (credential.proof.type !== SIGNATURE_TYPE_ED25519) {
268
- return {
269
- kind: "fail",
270
- errors: [
271
- `Invalid signature type: ${credential.proof.type}`
272
- ]
273
- };
274
- }
275
- const signData = getCredentialProofPayload(credential);
276
- if (!await (0, import_crypto4.verifySignature)(credential.proof.signer, signData, credential.proof.value)) {
277
- return {
278
- kind: "fail",
279
- errors: [
280
- "Invalid signature"
281
- ]
282
- };
283
- }
284
- return {
285
- kind: "pass"
286
- };
287
- };
288
- var verifyChain = async (chain, authority, subject) => {
289
- const result = await verifyCredential(chain.credential);
290
- if (result.kind === "fail") {
291
- return result;
292
- }
293
- if (!isValidAuthorizedDeviceCredential(chain.credential, authority, subject)) {
294
- return {
295
- kind: "fail",
296
- errors: [
297
- `Invalid credential chain: invalid assertion for key: ${subject}`
298
- ]
299
- };
300
- }
301
- return {
302
- kind: "pass"
303
- };
304
- };
305
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/credentials/credential-factory.ts";
306
- var createCredential = async ({ signer, issuer, subject, assertion, signingKey, chain, nonce, parentCredentialIds }) => {
307
- (0, import_invariant2.invariant)(assertion["@type"], "Invalid assertion.", {
308
- F: __dxlog_file2,
309
- L: 48,
310
- S: void 0,
311
- A: [
312
- "assertion['@type']",
313
- "'Invalid assertion.'"
314
- ]
315
- });
316
- (0, import_invariant2.invariant)(!!signingKey === !!chain, "Chain must be provided if and only if the signing key differs from the issuer.", {
317
- F: __dxlog_file2,
318
- L: 49,
319
- S: void 0,
320
- A: [
321
- "!!signingKey === !!chain",
322
- "'Chain must be provided if and only if the signing key differs from the issuer.'"
323
- ]
324
- });
325
- if (chain) {
326
- const result = await verifyChain(chain, issuer, signingKey);
327
- (0, import_invariant2.invariant)(result.kind === "pass", "Invalid chain.", {
328
- F: __dxlog_file2,
329
- L: 52,
330
- S: void 0,
331
- A: [
332
- "result.kind === 'pass'",
333
- "'Invalid chain.'"
334
- ]
335
- });
336
- }
337
- const credential = {
338
- issuer,
339
- issuanceDate: /* @__PURE__ */ new Date(),
340
- subject: {
341
- id: subject,
342
- assertion
343
- },
344
- parentCredentialIds,
345
- proof: {
346
- type: SIGNATURE_TYPE_ED25519,
347
- creationDate: /* @__PURE__ */ new Date(),
348
- signer: signingKey ?? issuer,
349
- value: new Uint8Array(),
350
- nonce
351
- }
352
- };
353
- const signedPayload = getCredentialProofPayload(credential);
354
- credential.proof.value = await signer.sign(signingKey ?? issuer, signedPayload);
355
- if (chain) {
356
- credential.proof.chain = chain;
357
- }
358
- credential.id = import_keys3.PublicKey.from(await import_crypto3.subtleCrypto.digest("SHA-256", signedPayload));
359
- return credential;
360
- };
361
- var createCredentialMessage = (credential) => {
362
- return {
363
- "@type": "dxos.echo.feed.CredentialsMessage",
364
- credential
365
- };
366
- };
367
- var createCredentialSignerWithKey = (signer, issuer) => ({
368
- getIssuer: () => issuer,
369
- createCredential: ({ subject, assertion, nonce, parentCredentialIds }) => createCredential({
370
- signer,
371
- issuer,
372
- subject,
373
- assertion,
374
- nonce,
375
- parentCredentialIds
376
- })
377
- });
378
- var createCredentialSignerWithChain = (signer, chain, signingKey) => ({
379
- getIssuer: () => chain.credential.issuer,
380
- createCredential: ({ subject, assertion, nonce, parentCredentialIds }) => createCredential({
381
- signer,
382
- issuer: chain.credential.issuer,
383
- signingKey,
384
- chain,
385
- subject,
386
- assertion,
387
- nonce,
388
- parentCredentialIds
389
- })
390
- });
391
- var CredentialGenerator = class {
392
- constructor(_signer, _identityKey, _deviceKey) {
393
- this._signer = _signer;
394
- this._identityKey = _identityKey;
395
- this._deviceKey = _deviceKey;
396
- }
397
- /**
398
- * Create genesis messages for new Space.
399
- */
400
- async createSpaceGenesis(spaceKey, controlKey, creatorProfile) {
401
- return [
402
- await createCredential({
403
- signer: this._signer,
404
- issuer: spaceKey,
405
- subject: spaceKey,
406
- assertion: {
407
- "@type": "dxos.halo.credentials.SpaceGenesis",
408
- spaceKey
409
- }
410
- }),
411
- await createCredential({
412
- signer: this._signer,
413
- issuer: spaceKey,
414
- subject: this._identityKey,
415
- assertion: {
416
- "@type": "dxos.halo.credentials.SpaceMember",
417
- spaceKey,
418
- role: import_credentials.SpaceMember.Role.ADMIN,
419
- profile: creatorProfile,
420
- genesisFeedKey: controlKey
421
- }
422
- }),
423
- await this.createFeedAdmission(spaceKey, controlKey, import_credentials.AdmittedFeed.Designation.CONTROL)
424
- ];
425
- }
426
- /**
427
- * Create invitation.
428
- * Admit identity and control and data feeds.
429
- */
430
- // TODO(burdon): Reconcile with above (esp. Signer).
431
- async createMemberInvitation(spaceKey, identityKey, deviceKey, controlKey, dataKey, genesisFeedKey) {
432
- return [
433
- await createCredential({
434
- signer: this._signer,
435
- issuer: this._identityKey,
436
- subject: identityKey,
437
- assertion: {
438
- "@type": "dxos.halo.credentials.SpaceMember",
439
- spaceKey,
440
- role: import_credentials.SpaceMember.Role.EDITOR,
441
- genesisFeedKey
442
- }
443
- }),
444
- await this.createFeedAdmission(spaceKey, controlKey, import_credentials.AdmittedFeed.Designation.CONTROL),
445
- await this.createFeedAdmission(spaceKey, dataKey, import_credentials.AdmittedFeed.Designation.DATA)
446
- ];
447
- }
448
- /**
449
- * Add device to space.
450
- */
451
- // TODO(burdon): Reconcile with below.
452
- async createDeviceAuthorization(deviceKey) {
453
- return createCredential({
454
- signer: this._signer,
455
- issuer: this._identityKey,
456
- subject: deviceKey,
457
- assertion: {
458
- "@type": "dxos.halo.credentials.AuthorizedDevice",
459
- identityKey: this._identityKey,
460
- deviceKey
461
- }
462
- });
463
- }
464
- /**
465
- * Add device metadata.
466
- */
467
- async createDeviceProfile(profile) {
468
- return createCredential({
469
- signer: this._signer,
470
- issuer: this._identityKey,
471
- subject: this._deviceKey,
472
- assertion: {
473
- "@type": "dxos.halo.credentials.DeviceProfile",
474
- profile
475
- }
476
- });
477
- }
478
- /**
479
- * Add feed to space.
480
- */
481
- async createFeedAdmission(spaceKey, feedKey, designation) {
482
- return createCredential({
483
- signer: this._signer,
484
- issuer: this._identityKey,
485
- subject: feedKey,
486
- assertion: {
487
- "@type": "dxos.halo.credentials.AdmittedFeed",
488
- spaceKey,
489
- identityKey: this._identityKey,
490
- deviceKey: this._deviceKey,
491
- designation
492
- }
493
- });
494
- }
495
- async createProfileCredential(profile) {
496
- return createCredential({
497
- signer: this._signer,
498
- issuer: this._identityKey,
499
- subject: this._identityKey,
500
- assertion: {
501
- "@type": "dxos.halo.credentials.IdentityProfile",
502
- profile
503
- }
504
- });
505
- }
506
- async createEpochCredential(spaceKey) {
507
- return createCredential({
508
- signer: this._signer,
509
- issuer: this._identityKey,
510
- subject: spaceKey,
511
- assertion: {
512
- "@type": "dxos.halo.credentials.Epoch",
513
- number: 0,
514
- timeframe: new import_timeframe2.Timeframe()
515
- }
516
- });
517
- }
518
- };
519
- var createDeviceAuthorization = async (signer, identityKey, deviceKey) => {
520
- const credentials = await Promise.all([
521
- await signer.createCredential({
522
- subject: deviceKey,
523
- assertion: {
524
- "@type": "dxos.halo.credentials.AuthorizedDevice",
525
- identityKey,
526
- deviceKey
527
- }
528
- })
529
- ]);
530
- return credentials.map((credential) => ({
531
- "@type": "dxos.echo.feed.CredentialsMessage",
532
- credential
533
- }));
534
- };
535
- var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFeedKey, role = import_credentials.SpaceMember.Role.ADMIN, membershipChainHeads = [], profile, invitationCredentialId) => {
536
- const credentials = await Promise.all([
537
- await signer.createCredential({
538
- subject: identityKey,
539
- parentCredentialIds: membershipChainHeads,
540
- assertion: {
541
- "@type": "dxos.halo.credentials.SpaceMember",
542
- spaceKey,
543
- role,
544
- profile,
545
- genesisFeedKey,
546
- invitationCredentialId
547
- }
548
- })
549
- ]);
550
- return credentials.map((credential) => ({
551
- credential: {
552
- credential
553
- }
554
- }));
555
- };
556
- var createDelegatedSpaceInvitationCredential = async (signer, subject, invitation) => {
557
- const credential = await signer.createCredential({
558
- subject,
559
- assertion: {
560
- "@type": "dxos.halo.invitations.DelegateSpaceInvitation",
561
- invitationId: invitation.invitationId,
562
- authMethod: invitation.authMethod,
563
- swarmKey: invitation.swarmKey,
564
- role: invitation.role,
565
- guestKey: invitation.guestKey,
566
- expiresOn: invitation.expiresOn,
567
- multiUse: invitation.multiUse
568
- }
569
- });
570
- return {
571
- credential: {
572
- credential
573
- }
574
- };
575
- };
576
- var createCancelDelegatedSpaceInvitationCredential = async (signer, subject, invitationCredentialId) => {
577
- const credential = await signer.createCredential({
578
- subject,
579
- assertion: {
580
- "@type": "dxos.halo.invitations.CancelDelegatedInvitation",
581
- credentialId: invitationCredentialId
582
- }
583
- });
584
- return {
585
- credential: {
586
- credential
587
- }
588
- };
589
- };
590
- var signPresentation = async ({ presentation, signer, signerKey, chain, nonce }) => {
591
- const proof = {
592
- type: SIGNATURE_TYPE_ED25519,
593
- value: new Uint8Array(),
594
- creationDate: /* @__PURE__ */ new Date(),
595
- signer: signerKey,
596
- nonce
597
- };
598
- const signedPayload = getPresentationProofPayload(presentation.credentials ?? [], proof);
599
- proof.value = await signer.sign(signerKey, signedPayload);
600
- if (chain) {
601
- proof.chain = chain;
602
- }
603
- return {
604
- credentials: presentation.credentials,
605
- proofs: [
606
- ...presentation.proofs ?? [],
607
- proof
608
- ]
609
- };
610
- };
611
- var verifyPresentation = async (presentation) => {
612
- const errors = [];
613
- const credentialsVerifications = await Promise.all(presentation.credentials?.map((credential) => verifyCredential(credential)) ?? []);
614
- for (const verification of credentialsVerifications) {
615
- if (verification.kind === "fail") {
616
- errors.push(...verification.errors);
617
- }
618
- }
619
- const proofVerification = await Promise.all(presentation.proofs?.map(async (proof) => {
620
- const chainVerification = await verifyPresentationChain(presentation, proof);
621
- if (chainVerification.kind === "fail") {
622
- return chainVerification;
623
- }
624
- const signatureVerification = await verifyPresentationSignature(presentation, proof);
625
- if (signatureVerification.kind === "fail") {
626
- return signatureVerification;
627
- }
628
- return {
629
- kind: "pass"
630
- };
631
- }) ?? []);
632
- for (const verification of proofVerification) {
633
- if (verification.kind === "fail") {
634
- errors.push(...verification.errors);
635
- }
636
- }
637
- if (errors.length === 0) {
638
- return {
639
- kind: "pass"
640
- };
641
- }
642
- {
643
- return {
644
- kind: "fail",
645
- errors
646
- };
647
- }
648
- };
649
- var verifyPresentationChain = async (presentation, proof) => {
650
- for (const credential of presentation.credentials ?? []) {
651
- if (!credential.issuer.equals(proof.signer)) {
652
- if (!proof.chain) {
653
- return {
654
- kind: "fail",
655
- errors: [
656
- "Delegated credential is missing credential chain."
657
- ]
658
- };
659
- }
660
- const chainVerification = await verifyChain(proof.chain, credential.subject.id, proof.signer);
661
- if (chainVerification.kind === "fail") {
662
- return chainVerification;
663
- }
664
- }
665
- }
666
- return {
667
- kind: "pass"
668
- };
669
- };
670
- var verifyPresentationSignature = async (presentation, proof) => {
671
- if (proof.type !== SIGNATURE_TYPE_ED25519) {
672
- return {
673
- kind: "fail",
674
- errors: [
675
- `Invalid signature type: ${proof.type}`
676
- ]
677
- };
678
- }
679
- const signData = getPresentationProofPayload(presentation.credentials ?? [], proof);
680
- if (!await (0, import_crypto5.verifySignature)(proof.signer, signData, proof.value)) {
681
- return {
682
- kind: "fail",
683
- errors: [
684
- "Invalid signature"
685
- ]
686
- };
687
- }
688
- return {
689
- kind: "pass"
690
- };
691
- };
692
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/state-machine/feed-state-machine.ts";
693
- var FeedStateMachine = class {
694
- constructor(_spaceKey) {
695
- this._spaceKey = _spaceKey;
696
- this._feeds = new import_util4.ComplexMap(import_keys5.PublicKey.hash);
697
- this.onFeedAdmitted = new import_util4.Callback();
698
- }
699
- get feeds() {
700
- return this._feeds;
701
- }
702
- /**
703
- * Processes the AdmittedFeed credential.
704
- * Assumes the credential is already pre-verified
705
- * and the issuer has been authorized to issue credentials of this type.
706
- * @param fromFeed Key of the feed where this credential is recorded.
707
- */
708
- async process(credential, fromFeed) {
709
- const assertion = getCredentialAssertion(credential);
710
- (0, import_invariant3.invariant)(assertion["@type"] === "dxos.halo.credentials.AdmittedFeed", void 0, {
711
- F: __dxlog_file3,
712
- L: 47,
713
- S: this,
714
- A: [
715
- "assertion['@type'] === 'dxos.halo.credentials.AdmittedFeed'",
716
- ""
717
- ]
718
- });
719
- (0, import_invariant3.invariant)(assertion.spaceKey.equals(this._spaceKey), void 0, {
720
- F: __dxlog_file3,
721
- L: 48,
722
- S: this,
723
- A: [
724
- "assertion.spaceKey.equals(this._spaceKey)",
725
- ""
726
- ]
727
- });
728
- const info = {
729
- key: credential.subject.id,
730
- credential,
731
- assertion,
732
- parent: fromFeed
733
- };
734
- this._feeds.set(credential.subject.id, info);
735
- await this.onFeedAdmitted.callIfSet(info);
736
- }
737
- };
738
- var InvitationStateMachine = class {
739
- constructor() {
740
- this._invitations = new import_util5.ComplexMap(import_keys6.PublicKey.hash);
741
- this._redeemedInvitationCredentialIds = new import_util5.ComplexSet(import_keys6.PublicKey.hash);
742
- this._cancelledInvitationCredentialIds = new import_util5.ComplexSet(import_keys6.PublicKey.hash);
743
- this.onDelegatedInvitation = new import_util5.Callback();
744
- this.onDelegatedInvitationRemoved = new import_util5.Callback();
745
- }
746
- get invitations() {
747
- return this._invitations;
748
- }
749
- async process(credential) {
750
- const credentialId = credential.id;
751
- if (credentialId == null) {
752
- return;
753
- }
754
- const assertion = getCredentialAssertion(credential);
755
- switch (assertion["@type"]) {
756
- case "dxos.halo.invitations.CancelDelegatedInvitation": {
757
- this._cancelledInvitationCredentialIds.add(assertion.credentialId);
758
- const existingInvitation = this._invitations.get(assertion.credentialId);
759
- if (existingInvitation != null) {
760
- this._invitations.delete(assertion.credentialId);
761
- await this.onDelegatedInvitationRemoved.callIfSet({
762
- credentialId: assertion.credentialId,
763
- invitation: existingInvitation
764
- });
765
- }
766
- break;
767
- }
768
- case "dxos.halo.invitations.DelegateSpaceInvitation": {
769
- if (credential.id) {
770
- const isExpired = assertion.expiresOn && assertion.expiresOn.getTime() < Date.now();
771
- const wasUsed = this._redeemedInvitationCredentialIds.has(credential.id) && !assertion.multiUse;
772
- const wasCancelled = this._cancelledInvitationCredentialIds.has(credential.id);
773
- if (isExpired || wasCancelled || wasUsed) {
774
- return;
775
- }
776
- const invitation = {
777
- ...assertion
778
- };
779
- this._invitations.set(credential.id, invitation);
780
- await this.onDelegatedInvitation.callIfSet({
781
- credentialId: credential.id,
782
- invitation
783
- });
784
- }
785
- break;
786
- }
787
- case "dxos.halo.credentials.SpaceMember": {
788
- if (assertion.invitationCredentialId != null) {
789
- this._redeemedInvitationCredentialIds.add(assertion.invitationCredentialId);
790
- const existingInvitation = this._invitations.get(assertion.invitationCredentialId);
791
- if (existingInvitation != null && !existingInvitation.multiUse) {
792
- this._invitations.delete(assertion.invitationCredentialId);
793
- await this.onDelegatedInvitationRemoved.callIfSet({
794
- credentialId: assertion.invitationCredentialId,
795
- invitation: existingInvitation
796
- });
797
- }
798
- }
799
- break;
800
- }
801
- }
802
- }
803
- };
804
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/graph/credential-graph.ts";
805
- var CredentialGraph = class {
806
- constructor(_stateHandler) {
807
- this._stateHandler = _stateHandler;
808
- this._vertexIdGenerator = 1;
809
- this._root = {
810
- id: -1,
811
- parents: [],
812
- children: []
813
- };
814
- this._sentinel = {
815
- id: -2,
816
- parents: [],
817
- children: []
818
- };
819
- this._vertexByCredentialId = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
820
- this._subjectToVertex = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
821
- this._subjectToState = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
822
- this.onSubjectStateChanged = new import_util7.Callback();
823
- }
824
- getSubjectState(subjectId) {
825
- return this._subjectToState.get(subjectId);
826
- }
827
- getState() {
828
- return this._subjectToState;
829
- }
830
- getLeafIds() {
831
- return this._sentinel.parents.map((v) => v.credential.id);
832
- }
833
- getGlobalStateScope() {
834
- return {
835
- state: this._subjectToVertex
836
- };
837
- }
838
- addVertex(credential, assertion) {
839
- const newVertex = {
840
- id: this._vertexIdGenerator++,
841
- credential,
842
- assertion,
843
- parents: [],
844
- children: []
845
- };
846
- this._vertexByCredentialId.set(credential.id, newVertex);
847
- const parentIds = credential.parentCredentialIds ?? [];
848
- if (parentIds.length === 0) {
849
- this._root.children.push(newVertex);
850
- newVertex.parents.push(this._root);
851
- } else {
852
- for (const parentId of parentIds) {
853
- const parentVertex = this._vertexByCredentialId.get(parentId);
854
- if (parentVertex == null) {
855
- import_log3.log.error("credential skipped because of the unknown parent", {
856
- credential,
857
- parentId
858
- }, {
859
- F: __dxlog_file4,
860
- L: 72,
861
- S: this,
862
- C: (f, a) => f(...a)
863
- });
864
- continue;
865
- }
866
- parentVertex.children.push(newVertex);
867
- newVertex.parents.push(parentVertex);
868
- this._removeSentinelConnection(parentVertex);
869
- }
870
- }
871
- newVertex.children.push(this._sentinel);
872
- this._sentinel.parents.push(newVertex);
873
- return this._onVertexInserted(newVertex);
874
- }
875
- _removeSentinelConnection(vertex) {
876
- const sentinelIdx = vertex.children.indexOf(this._sentinel);
877
- if (sentinelIdx >= 0) {
878
- vertex.children.splice(sentinelIdx, 1);
879
- const vertexInSentinelIdx = this._sentinel.parents.indexOf(vertex);
880
- (0, import_invariant5.invariant)(vertexInSentinelIdx >= 0, void 0, {
881
- F: __dxlog_file4,
882
- L: 90,
883
- S: this,
884
- A: [
885
- "vertexInSentinelIdx >= 0",
886
- ""
887
- ]
888
- });
889
- this._sentinel.parents.splice(vertexInSentinelIdx, 1);
890
- }
891
- }
892
- async _onVertexInserted(newVertex) {
893
- const { credential, assertion } = newVertex;
894
- (0, import_invariant5.invariant)(credential, void 0, {
895
- F: __dxlog_file4,
896
- L: 97,
897
- S: this,
898
- A: [
899
- "credential",
900
- ""
901
- ]
902
- });
903
- let changedSubjects = [];
904
- const isUpdateAppliedOnTopOfThePreviousState = this._sentinel.parents.length === 1;
905
- if (isUpdateAppliedOnTopOfThePreviousState) {
906
- const subjectId = credential.subject.id;
907
- if (this._stateHandler.isUpdateAllowed(this.getGlobalStateScope(), credential, assertion)) {
908
- const newSubjectState = this._stateHandler.createState(credential, newVertex.assertion);
909
- const prevSubjectState = this._subjectToState.get(subjectId);
910
- this._subjectToState.set(subjectId, newSubjectState);
911
- this._subjectToVertex.set(subjectId, newVertex);
912
- if (this._stateHandler.hasStateChanged(newSubjectState, prevSubjectState)) {
913
- changedSubjects.push(newSubjectState);
914
- }
915
- }
916
- } else {
917
- changedSubjects = this._recomputeState();
918
- }
919
- if (changedSubjects.length > 0) {
920
- await this.onSubjectStateChanged.callIfSet(changedSubjects);
921
- }
922
- }
923
- /**
924
- * DFS the graph from root to sentinel pausing on merge points (nodes with multiple parents).
925
- * Continue after all paths leading to a merge point converge by merging their states.
926
- * In case of a concurrent update paths are replayed taking into account the state set
927
- * by the winning branch.
928
- */
929
- _recomputeState() {
930
- const pendingPaths = /* @__PURE__ */ new Map();
931
- const paths = [
932
- this._createRootPath()
933
- ];
934
- let lastPath = null;
935
- while (lastPath == null) {
936
- const path = paths.pop();
937
- (0, import_log3.log)("visit vertex", {
938
- id: path.head.id
939
- }, {
940
- F: __dxlog_file4,
941
- L: 132,
942
- S: this,
943
- C: (f, a) => f(...a)
944
- });
945
- this._updatePathState(path);
946
- const convergedPaths = this._handleMergePoint(paths, pendingPaths, path);
947
- if (convergedPaths == null) {
948
- (0, import_log3.log)("waiting for other paths", void 0, {
949
- F: __dxlog_file4,
950
- L: 136,
951
- S: this,
952
- C: (f, a) => f(...a)
953
- });
954
- continue;
955
- }
956
- const mergeResult = this._mergePaths(convergedPaths);
957
- if (mergeResult.type === "replay_required") {
958
- this._replayFailedPaths(paths, pendingPaths, mergeResult, convergedPaths);
959
- continue;
960
- }
961
- const merged = mergeResult.path;
962
- if (merged.head.children.length === 0) {
963
- lastPath = merged;
964
- } else if (merged.head.children.length === 1) {
965
- merged.head = merged.head.children[0];
966
- paths.push(merged);
967
- } else {
968
- this._forkTraversal(paths, merged);
969
- }
970
- }
971
- if (paths.length > 0) {
972
- import_log3.log.error("traversal finished while there were active paths", {
973
- paths: paths.map((p) => ({
974
- path: toChosenPath(p),
975
- head: p.head.id
976
- }))
977
- }, {
978
- F: __dxlog_file4,
979
- L: 155,
980
- S: this,
981
- C: (f, a) => f(...a)
982
- });
983
- }
984
- return this._setCurrentState(lastPath);
985
- }
986
- _replayFailedPaths(paths, pendingPaths, mergeResult, convergedPaths) {
987
- paths.push(...mergeResult.replay.map((path) => {
988
- const stateOverrides = path.stateOverrides ?? new import_util7.ComplexMap(import_keys8.PublicKey.hash);
989
- mergeResult.stateOverrides.forEach((value, key) => stateOverrides.set(key, value));
990
- return {
991
- ...mergeResult.from,
992
- chosenPath: path.chosenPath,
993
- stateOverrides
994
- };
995
- }));
996
- (0, import_log3.log)("replay paths", () => ({
997
- count: paths.length,
998
- paths: paths.map((path) => ({
999
- from: mergeResult.from.head.id,
1000
- path: toChosenPath(path),
1001
- overrides: path?.stateOverrides?.mapValues((v) => this._stateHandler.toLogString(v.assertion))
1002
- }))
1003
- }), {
1004
- F: __dxlog_file4,
1005
- L: 175,
1006
- S: this,
1007
- C: (f, a) => f(...a)
1008
- });
1009
- const clearedPending = convergedPaths.filter((l) => !mergeResult.replay.includes(l));
1010
- pendingPaths.set(convergedPaths[0].head.id, clearedPending);
1011
- }
1012
- _handleMergePoint(paths, pendingPaths, path) {
1013
- const pendingList = pendingPaths.get(path.head.id) ?? [];
1014
- pendingPaths.set(path.head.id, pendingList);
1015
- pendingList.push(path);
1016
- if (pendingList.length < path.head.parents.length) {
1017
- return null;
1018
- }
1019
- if (path.head.id === this._sentinel.id && paths.length > 0) {
1020
- (0, import_log3.log)("waiting for all the active paths to converge on the sentinel", void 0, {
1021
- F: __dxlog_file4,
1022
- L: 199,
1023
- S: this,
1024
- C: (f, a) => f(...a)
1025
- });
1026
- return null;
1027
- }
1028
- pendingPaths.delete(path.head.id);
1029
- return pendingList;
1030
- }
1031
- _updatePathState(path) {
1032
- const headCredential = path.head.credential;
1033
- if (headCredential == null) {
1034
- return;
1035
- }
1036
- const updatedSubject = headCredential.subject.id;
1037
- path.credentials.add(headCredential.id);
1038
- let isUpdateAllowed = this._stateHandler.isUpdateAllowed(path, headCredential, path.head.assertion);
1039
- if (!isUpdateAllowed && path.head.parents[0]?.id === this._root.id) {
1040
- const globalState = this.getGlobalStateScope();
1041
- isUpdateAllowed = this._stateHandler.isUpdateAllowed(globalState, headCredential, path.head.assertion);
1042
- }
1043
- if (isUpdateAllowed) {
1044
- path.forkChangedSubjects.add(updatedSubject);
1045
- path.forkIssuers.add(headCredential.issuer);
1046
- path.state.set(updatedSubject, path.head);
1047
- (0, import_log3.log)("path state updated", () => ({
1048
- subject: updatedSubject,
1049
- newState: this._stateHandler.toLogString(path.head.assertion)
1050
- }), {
1051
- F: __dxlog_file4,
1052
- L: 223,
1053
- S: this,
1054
- C: (f, a) => f(...a)
1055
- });
1056
- }
1057
- }
1058
- _forkTraversal(paths, path) {
1059
- const replayChoice = path.chosenPath?.[path.head.id];
1060
- const choices = replayChoice ?? path.head.children;
1061
- for (const choice of choices) {
1062
- (0, import_log3.log)("edge traversal", {
1063
- from: path.head.id,
1064
- to: choice.id
1065
- }, {
1066
- F: __dxlog_file4,
1067
- L: 234,
1068
- S: this,
1069
- C: (f, a) => f(...a)
1070
- });
1071
- const fork = {
1072
- forkPoint: path,
1073
- chosenPath: {
1074
- ...path.chosenPath,
1075
- [path.head.id]: [
1076
- choice
1077
- ]
1078
- },
1079
- head: choice,
1080
- credentials: new import_util7.ComplexSet(import_keys8.PublicKey.hash, path.credentials),
1081
- state: new import_util7.ComplexMap(import_keys8.PublicKey.hash, [
1082
- ...path.state.entries()
1083
- ]),
1084
- forkIssuers: new import_util7.ComplexSet(import_keys8.PublicKey.hash),
1085
- forkChangedSubjects: new import_util7.ComplexSet(import_keys8.PublicKey.hash),
1086
- stateOverrides: path.stateOverrides
1087
- };
1088
- paths.push(fork);
1089
- }
1090
- }
1091
- /**
1092
- * Updates the current graph state.
1093
- * @returns changed states.
1094
- */
1095
- _setCurrentState(path) {
1096
- const changedSubjects = [];
1097
- const newStateMap = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
1098
- const newVertexMap = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
1099
- for (const [subjectKey, subjectVertex] of path.state.entries()) {
1100
- const newState = this._stateHandler.createState(subjectVertex.credential, subjectVertex.assertion);
1101
- const prevState = this._subjectToState.get(subjectKey);
1102
- newStateMap.set(subjectKey, newState);
1103
- newVertexMap.set(subjectKey, subjectVertex);
1104
- if (this._stateHandler.hasStateChanged(newState, prevState)) {
1105
- changedSubjects.push(newState);
1106
- }
1107
- }
1108
- this._subjectToState = newStateMap;
1109
- this._subjectToVertex = newVertexMap;
1110
- return changedSubjects;
1111
- }
1112
- /*
1113
- * Walk up all the fork points and return the first one present in all the paths.
1114
- * We use local id to determine vertex position in the graph, because nodes can't
1115
- * be inserted in the middle (between a parent and a child) and ids are monotonically increasing.
1116
- */
1117
- _leastCommonAncestor(paths) {
1118
- const uniqueForkPoints = paths.reduce((acc, path) => {
1119
- let it = path.forkPoint;
1120
- while (it) {
1121
- acc.set(it.head.id, it);
1122
- it = it.forkPoint;
1123
- }
1124
- return acc;
1125
- }, /* @__PURE__ */ new Map());
1126
- let maxId = this._root.id;
1127
- let maxState = null;
1128
- for (const [id, state] of uniqueForkPoints.entries()) {
1129
- const headCredential = state.head.credential;
1130
- if (headCredential != null) {
1131
- const isPointInEveryPath = paths.every((p) => p.credentials.has(headCredential.id));
1132
- if (isPointInEveryPath && id > maxId) {
1133
- maxId = id;
1134
- maxState = state;
1135
- }
1136
- }
1137
- }
1138
- return maxState ?? this._createRootPath();
1139
- }
1140
- /**
1141
- * We might be merging paths where some of them had fork points after the initial forking.
1142
- * We need all the paths to point to the least common fork point and contain all the changes
1143
- * that happened after it.
1144
- */
1145
- _moveUpToForkPoint(forkPoint, path) {
1146
- const isForkPointInPath = path.chosenPath[forkPoint.head.id] == null || path.forkPoint == null;
1147
- if (isForkPointInPath) {
1148
- return path;
1149
- }
1150
- if (forkPoint.head.id === path.forkPoint?.head.id) {
1151
- return path;
1152
- }
1153
- let it = path.forkPoint;
1154
- while (it.head.id !== forkPoint.head.id) {
1155
- it.forkIssuers.forEach((iss) => path.forkIssuers.add(iss));
1156
- it.forkChangedSubjects.forEach((m) => path.forkChangedSubjects.add(m));
1157
- it = it.forkPoint;
1158
- path.forkPoint = it;
1159
- }
1160
- return path;
1161
- }
1162
- _mergePaths(convergedPaths) {
1163
- (0, import_invariant5.invariant)(convergedPaths.length >= 1, void 0, {
1164
- F: __dxlog_file4,
1165
- L: 324,
1166
- S: this,
1167
- A: [
1168
- "convergedPaths.length >= 1",
1169
- ""
1170
- ]
1171
- });
1172
- if (convergedPaths.length === 1) {
1173
- return {
1174
- type: "merged",
1175
- path: convergedPaths[0]
1176
- };
1177
- }
1178
- const forkPoint = this._leastCommonAncestor(convergedPaths);
1179
- (0, import_log3.log)("merging paths", () => ({
1180
- forkPointId: forkPoint.head.id,
1181
- pathCount: convergedPaths.length,
1182
- forkPoints: convergedPaths.map((fp) => fp.forkPoint?.head.id)
1183
- }), {
1184
- F: __dxlog_file4,
1185
- L: 329,
1186
- S: this,
1187
- C: (f, a) => f(...a)
1188
- });
1189
- const paths = convergedPaths.map((p) => this._moveUpToForkPoint(forkPoint, p));
1190
- (0, import_invariant5.invariant)(forkPoint, void 0, {
1191
- F: __dxlog_file4,
1192
- L: 335,
1193
- S: this,
1194
- A: [
1195
- "forkPoint",
1196
- ""
1197
- ]
1198
- });
1199
- const result = {
1200
- forkPoint: forkPoint.forkPoint,
1201
- chosenPath: {
1202
- ...forkPoint.chosenPath,
1203
- [forkPoint.head.id]: []
1204
- },
1205
- stateOverrides: forkPoint.stateOverrides,
1206
- credentials: new import_util7.ComplexSet(import_keys8.PublicKey.hash, forkPoint.credentials),
1207
- forkIssuers: new import_util7.ComplexSet(import_keys8.PublicKey.hash, forkPoint.forkIssuers),
1208
- forkChangedSubjects: new import_util7.ComplexSet(import_keys8.PublicKey.hash, forkPoint.forkChangedSubjects),
1209
- state: forkPoint.state.mapValues((v) => v),
1210
- head: paths[0].head
1211
- };
1212
- const subjectToBranch = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
1213
- for (const path of paths) {
1214
- (0, import_log3.log)("processing a path", () => ({
1215
- choices: toChosenPath(path),
1216
- modified: path.forkChangedSubjects,
1217
- forkIssuers: path.forkIssuers,
1218
- state: path.state.mapValues((v) => this._stateHandler.toLogString(v.assertion))
1219
- }), {
1220
- F: __dxlog_file4,
1221
- L: 348,
1222
- S: this,
1223
- C: (f, a) => f(...a)
1224
- });
1225
- path.forkIssuers.forEach((iss) => result.forkIssuers.add(iss));
1226
- path.credentials.forEach((cred) => result.credentials.add(cred));
1227
- result.chosenPath[forkPoint.head.id].push(...path.chosenPath[forkPoint.head.id] ?? []);
1228
- for (const modifiedSubject of path.forkChangedSubjects) {
1229
- const existingBranch = subjectToBranch.get(modifiedSubject);
1230
- if (existingBranch == null || this._shouldOverrideCredential(existingBranch, path, modifiedSubject)) {
1231
- subjectToBranch.set(modifiedSubject, path);
1232
- }
1233
- }
1234
- }
1235
- const replayPaths = /* @__PURE__ */ new Set();
1236
- const addReplayPath = replayPaths.add.bind(replayPaths);
1237
- for (const [subject, branch] of subjectToBranch.entries()) {
1238
- result.forkChangedSubjects.add(subject);
1239
- const vertex = branch.state.get(subject);
1240
- result.state.set(subject, vertex);
1241
- (0, import_log3.log)("set subject state", () => ({
1242
- subject,
1243
- state: this._stateHandler.toLogString(vertex.assertion)
1244
- }), {
1245
- F: __dxlog_file4,
1246
- L: 370,
1247
- S: this,
1248
- C: (f, a) => f(...a)
1249
- });
1250
- const otherPaths = paths.filter((p) => p !== branch);
1251
- this._stateHandler.getConflictingPaths(otherPaths, vertex).forEach(addReplayPath);
1252
- }
1253
- if (replayPaths.size > 0) {
1254
- return {
1255
- type: "replay_required",
1256
- replay: [
1257
- ...replayPaths.values()
1258
- ],
1259
- from: forkPoint,
1260
- stateOverrides: subjectToBranch.mapValues((v, key) => v.state.get(key))
1261
- };
1262
- }
1263
- return {
1264
- type: "merged",
1265
- path: result
1266
- };
1267
- }
1268
- /**
1269
- * A candidate credential is preferred over the existing credential if:
1270
- * 1. It is the merge-point, because it's the last credential that was issued in awareness of all
1271
- * the previously existing ones.
1272
- * 2. A path where candidate was set contains existing credential in it, which means that the candidate
1273
- * was issued after the existing credential by a legitimate issuer.
1274
- * 3. A state-specific logic (_stateHandler) is able to justify using the candidate credential.
1275
- * 4. The path where candidate was set has more issuers than the existing path (longer branch).
1276
- * 5. The issuance time of the candidate is after the issuance time of the existing credential (LWW).
1277
- */
1278
- _shouldOverrideCredential(existing, candidate, modifiedSubject) {
1279
- const candidateVertex = candidate.state.get(modifiedSubject);
1280
- const currentVertex = existing.state.get(modifiedSubject);
1281
- if (candidateVertex.id === currentVertex.id) {
1282
- return false;
1283
- }
1284
- const mergePointId = existing.head.id;
1285
- if (candidateVertex.id === mergePointId || currentVertex.id === mergePointId) {
1286
- (0, import_log3.log)("merge point chosen to break the tie", {
1287
- mergePointId: existing.head.id
1288
- }, {
1289
- F: __dxlog_file4,
1290
- L: 408,
1291
- S: this,
1292
- C: (f, a) => f(...a)
1293
- });
1294
- return mergePointId === candidateVertex.id;
1295
- }
1296
- const candidateCredential = candidateVertex.credential;
1297
- const currentCredential = currentVertex.credential;
1298
- if (existing.credentials.has(candidateCredential.id) !== candidate.credentials.has(currentCredential.id)) {
1299
- (0, import_log3.log)("one of the credentials was overridden in another branch", {
1300
- current: currentVertex.id,
1301
- candidate: candidateVertex.id
1302
- }, {
1303
- F: __dxlog_file4,
1304
- L: 415,
1305
- S: this,
1306
- C: (f, a) => f(...a)
1307
- });
1308
- return candidate.credentials.has(currentCredential.id);
1309
- }
1310
- const winningCredential = this._stateHandler.tryPickWinningUpdate(existing, currentCredential, candidate, candidateCredential);
1311
- if (winningCredential != null) {
1312
- return winningCredential === candidateCredential;
1313
- }
1314
- if (candidate.forkIssuers.size !== existing.forkIssuers.size) {
1315
- (0, import_log3.log)("longer issuers branch used to break the tie", {
1316
- issuerCount: [
1317
- existing.forkIssuers.size,
1318
- candidate.forkIssuers.size
1319
- ]
1320
- }, {
1321
- F: __dxlog_file4,
1322
- L: 432,
1323
- S: this,
1324
- C: (f, a) => f(...a)
1325
- });
1326
- return candidate.forkIssuers.size > existing.forkIssuers.size;
1327
- }
1328
- (0, import_log3.log)("issuance date used to break the tie", void 0, {
1329
- F: __dxlog_file4,
1330
- L: 437,
1331
- S: this,
1332
- C: (f, a) => f(...a)
1333
- });
1334
- return candidateCredential.issuanceDate.getTime() > currentCredential.issuanceDate.getTime();
1335
- }
1336
- _createRootPath() {
1337
- return {
1338
- head: this._root,
1339
- chosenPath: {},
1340
- forkIssuers: new import_util7.ComplexSet(import_keys8.PublicKey.hash),
1341
- forkChangedSubjects: new import_util7.ComplexSet(import_keys8.PublicKey.hash),
1342
- state: new import_util7.ComplexMap(import_keys8.PublicKey.hash),
1343
- credentials: new import_util7.ComplexSet(import_keys8.PublicKey.hash)
1344
- };
1345
- }
1346
- };
1347
- var toChosenPath = (path) => {
1348
- return Object.fromEntries(Object.entries(path.chosenPath).map(([k, vs]) => [
1349
- k,
1350
- vs.map((v) => v.id)
1351
- ]));
1352
- };
1353
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/state-machine/member-state-machine.ts";
1354
- var MemberStateMachine = class {
1355
- constructor(_spaceKey) {
1356
- this._spaceKey = _spaceKey;
1357
- this._memberProfiles = new import_util6.ComplexMap(import_keys7.PublicKey.hash);
1358
- this._hashgraph = new CredentialGraph(this);
1359
- this.onMemberRoleChanged = this._hashgraph.onSubjectStateChanged;
1360
- }
1361
- get creator() {
1362
- return this._ownerKey && this._hashgraph.getSubjectState(this._ownerKey);
1363
- }
1364
- get members() {
1365
- return this._hashgraph.getState();
1366
- }
1367
- get membershipChainHeads() {
1368
- return this._hashgraph.getLeafIds();
1369
- }
1370
- getRole(member) {
1371
- return this._getRole(this._hashgraph.getGlobalStateScope(), member);
1372
- }
1373
- /**
1374
- * Processes the SpaceMember credential.
1375
- * Assumes the credential is already pre-verified and the issuer has been authorized to issue credentials of this type.
1376
- */
1377
- async process(credential) {
1378
- const assertion = getCredentialAssertion(credential);
1379
- switch (assertion["@type"]) {
1380
- case "dxos.halo.credentials.SpaceMember": {
1381
- (0, import_invariant4.invariant)(assertion.spaceKey.equals(this._spaceKey), void 0, {
1382
- F: __dxlog_file5,
1383
- L: 66,
1384
- S: this,
1385
- A: [
1386
- "assertion.spaceKey.equals(this._spaceKey)",
1387
- ""
1388
- ]
1389
- });
1390
- if (this._ownerKey == null && credential.issuer === this._spaceKey) {
1391
- this._ownerKey = credential.subject.id;
1392
- }
1393
- if (assertion.profile != null) {
1394
- this._memberProfiles.set(credential.subject.id, assertion.profile);
1395
- }
1396
- await this._hashgraph.addVertex(credential, assertion);
1397
- break;
1398
- }
1399
- case "dxos.halo.credentials.MemberProfile": {
1400
- const member = this._hashgraph.getSubjectState(credential.subject.id);
1401
- if (member) {
1402
- member.profile = assertion.profile;
1403
- } else {
1404
- import_log2.log.warn("Member not found", {
1405
- id: credential.subject.id
1406
- }, {
1407
- F: __dxlog_file5,
1408
- L: 81,
1409
- S: this,
1410
- C: (f, a) => f(...a)
1411
- });
1412
- }
1413
- this._memberProfiles.set(credential.subject.id, assertion.profile);
1414
- break;
1415
- }
1416
- default:
1417
- throw new Error("Invalid assertion type");
1418
- }
1419
- }
1420
- createState(credential, assertion) {
1421
- const memberKey = credential.subject.id;
1422
- return {
1423
- key: memberKey,
1424
- role: assertion.role,
1425
- credential,
1426
- assertion,
1427
- profile: this._memberProfiles.get(memberKey)
1428
- };
1429
- }
1430
- isUpdateAllowed(scope, credential, assertion) {
1431
- if (assertion.role === import_credentials3.SpaceMember.Role.OWNER) {
1432
- return credential.issuer.equals(this._spaceKey);
1433
- }
1434
- const issuer = credential.issuer;
1435
- const isChangingOwnRole = issuer.equals(credential.subject.id);
1436
- if (isChangingOwnRole) {
1437
- return false;
1438
- }
1439
- if (issuer.equals(assertion.spaceKey)) {
1440
- return true;
1441
- }
1442
- const issuerRole = this._getRole(scope, issuer);
1443
- return issuerRole === import_credentials3.SpaceMember.Role.ADMIN || issuerRole === import_credentials3.SpaceMember.Role.OWNER;
1444
- }
1445
- getConflictingPaths(paths, update) {
1446
- if (update.assertion.role !== import_credentials3.SpaceMember.Role.REMOVED && update.assertion.role !== import_credentials3.SpaceMember.Role.EDITOR) {
1447
- return [];
1448
- }
1449
- const memberId = update.credential.subject.id;
1450
- return paths.filter((p) => p.forkIssuers.has(memberId));
1451
- }
1452
- tryPickWinningUpdate(scope1, update1, scope2, update2) {
1453
- const path1IssuerRole = this._getRole(scope1, update1.issuer);
1454
- const path2IssuerRole = this._getRole(scope2, update2.issuer);
1455
- if (path2IssuerRole === import_credentials3.SpaceMember.Role.OWNER !== (path1IssuerRole === import_credentials3.SpaceMember.Role.OWNER)) {
1456
- (0, import_log2.log)("owner decision used to break the tie", void 0, {
1457
- F: __dxlog_file5,
1458
- L: 139,
1459
- S: this,
1460
- C: (f, a) => f(...a)
1461
- });
1462
- return path1IssuerRole === import_credentials3.SpaceMember.Role.OWNER ? update1 : update2;
1463
- }
1464
- return null;
1465
- }
1466
- toLogString(assertion) {
1467
- const role = assertion?.role ?? import_credentials3.SpaceMember.Role.REMOVED;
1468
- return Object.entries(import_credentials3.SpaceMember.Role).find(([_, value]) => value === role)[0];
1469
- }
1470
- hasStateChanged(s1, s2) {
1471
- return s1?.role !== s2?.role;
1472
- }
1473
- _getRole(scope, memberId) {
1474
- if (this._ownerKey?.equals(memberId)) {
1475
- return import_credentials3.SpaceMember.Role.OWNER;
1476
- }
1477
- const realRole = scope.state.get(memberId)?.assertion?.role ?? import_credentials3.SpaceMember.Role.REMOVED;
1478
- if (scope.stateOverrides != null) {
1479
- const override = scope.stateOverrides.get(memberId);
1480
- if (override != null) {
1481
- (0, import_log2.log)("member role overridden in path", () => ({
1482
- headId: scope.head?.id,
1483
- roleOverride: this.toLogString(override.assertion),
1484
- realRole: this.toLogString(scope.state.get(memberId)?.assertion)
1485
- }), {
1486
- F: __dxlog_file5,
1487
- L: 162,
1488
- S: this,
1489
- C: (f, a) => f(...a)
1490
- });
1491
- return override.assertion.role;
1492
- }
1493
- }
1494
- return realRole;
1495
- }
1496
- };
1497
- function _ts_decorate(decorators, target, key, desc) {
1498
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1499
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1500
- 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;
1501
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1502
- }
1503
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/state-machine/space-state-machine.ts";
1504
- var SpaceStateMachine = class {
1505
- constructor(_spaceKey) {
1506
- this._spaceKey = _spaceKey;
1507
- this._members = new MemberStateMachine(this._spaceKey);
1508
- this._feeds = new FeedStateMachine(this._spaceKey);
1509
- this._invitations = new InvitationStateMachine();
1510
- this._credentials = [];
1511
- this._credentialsById = new import_util3.ComplexMap(import_keys4.PublicKey.hash);
1512
- this._processedCredentials = new import_util3.ComplexSet(import_keys4.PublicKey.hash);
1513
- this._credentialProcessors = [];
1514
- this.onCredentialProcessed = new import_util3.Callback();
1515
- this.onMemberRoleChanged = this._members.onMemberRoleChanged;
1516
- this.onFeedAdmitted = this._feeds.onFeedAdmitted;
1517
- this.onDelegatedInvitation = this._invitations.onDelegatedInvitation;
1518
- this.onDelegatedInvitationRemoved = this._invitations.onDelegatedInvitationRemoved;
1519
- }
1520
- get creator() {
1521
- return this._members.creator;
1522
- }
1523
- get members() {
1524
- return this._members.members;
1525
- }
1526
- get membershipChainHeads() {
1527
- return this._members.membershipChainHeads;
1528
- }
1529
- get feeds() {
1530
- return this._feeds.feeds;
1531
- }
1532
- get credentials() {
1533
- return this._credentials.map((entry) => entry.credential);
1534
- }
1535
- get credentialEntries() {
1536
- return this._credentials;
1537
- }
1538
- get genesisCredential() {
1539
- return this._genesisCredential;
1540
- }
1541
- get invitations() {
1542
- return this._invitations.invitations;
1543
- }
1544
- async addCredentialProcessor(processor) {
1545
- if (this._credentialProcessors.find((p) => p.processor === processor)) {
1546
- throw new Error("Credential processor already added.");
1547
- }
1548
- const consumer = new CredentialConsumer(processor, async () => {
1549
- for (const credential of this.credentials) {
1550
- await consumer._process(credential);
1551
- }
1552
- consumer._isReadyForLiveCredentials = true;
1553
- }, async () => {
1554
- this._credentialProcessors = this._credentialProcessors.filter((p) => p !== consumer);
1555
- });
1556
- this._credentialProcessors.push(consumer);
1557
- await consumer.open();
1558
- }
1559
- async removeCredentialProcessor(processor) {
1560
- const consumer = this._credentialProcessors.find((p) => p.processor === processor);
1561
- await consumer?.close();
1562
- }
1563
- getCredentialsOfType(type) {
1564
- return this.credentials.filter((credential) => getCredentialAssertion(credential)["@type"] === type);
1565
- }
1566
- /**
1567
- * @param credential Message to process.
1568
- * @param fromFeed Key of the feed where this credential is recorded.
1569
- */
1570
- async process(credential, { sourceFeed, skipVerification }) {
1571
- if (credential.id) {
1572
- if (this._processedCredentials.has(credential.id)) {
1573
- return true;
1574
- }
1575
- this._processedCredentials.add(credential.id);
1576
- }
1577
- if (!skipVerification) {
1578
- const result = await verifyCredential(credential);
1579
- if (result.kind !== "pass") {
1580
- import_log.log.warn(`Invalid credential: ${result.errors.join(", ")}`, void 0, {
1581
- F: __dxlog_file6,
1582
- L: 156,
1583
- S: this,
1584
- C: (f, a) => f(...a)
1585
- });
1586
- return false;
1587
- }
1588
- }
1589
- const assertion = getCredentialAssertion(credential);
1590
- switch (assertion["@type"]) {
1591
- case "dxos.halo.credentials.SpaceGenesis": {
1592
- if (this._genesisCredential) {
1593
- import_log.log.warn("Space already has a genesis credential.", void 0, {
1594
- F: __dxlog_file6,
1595
- L: 165,
1596
- S: this,
1597
- C: (f, a) => f(...a)
1598
- });
1599
- return false;
1600
- }
1601
- if (!credential.issuer.equals(this._spaceKey)) {
1602
- import_log.log.warn("Space genesis credential must be issued by space.", void 0, {
1603
- F: __dxlog_file6,
1604
- L: 169,
1605
- S: this,
1606
- C: (f, a) => f(...a)
1607
- });
1608
- return false;
1609
- }
1610
- if (!credential.subject.id.equals(this._spaceKey)) {
1611
- import_log.log.warn("Space genesis credential must be issued to space.", void 0, {
1612
- F: __dxlog_file6,
1613
- L: 173,
1614
- S: this,
1615
- C: (f, a) => f(...a)
1616
- });
1617
- return false;
1618
- }
1619
- this._genesisCredential = credential;
1620
- break;
1621
- }
1622
- case "dxos.halo.credentials.SpaceMember": {
1623
- if (!assertion.spaceKey.equals(this._spaceKey)) {
1624
- break;
1625
- }
1626
- if (!this._genesisCredential) {
1627
- import_log.log.warn("Space must have a genesis credential before adding members.", void 0, {
1628
- F: __dxlog_file6,
1629
- L: 186,
1630
- S: this,
1631
- C: (f, a) => f(...a)
1632
- });
1633
- return false;
1634
- }
1635
- if (!this._canInviteNewMembers(credential.issuer)) {
1636
- import_log.log.warn(`Space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
1637
- F: __dxlog_file6,
1638
- L: 190,
1639
- S: this,
1640
- C: (f, a) => f(...a)
1641
- });
1642
- return false;
1643
- }
1644
- await this._members.process(credential);
1645
- await this._invitations.process(credential);
1646
- break;
1647
- }
1648
- case "dxos.halo.credentials.MemberProfile": {
1649
- if (!this._genesisCredential) {
1650
- import_log.log.warn("Space must have a genesis credential before adding members.", void 0, {
1651
- F: __dxlog_file6,
1652
- L: 201,
1653
- S: this,
1654
- C: (f, a) => f(...a)
1655
- });
1656
- return false;
1657
- }
1658
- await this._members.process(credential);
1659
- break;
1660
- }
1661
- case "dxos.halo.credentials.AdmittedFeed": {
1662
- if (!this._genesisCredential) {
1663
- import_log.log.warn("Space must have a genesis credential before admitting feeds.", void 0, {
1664
- F: __dxlog_file6,
1665
- L: 211,
1666
- S: this,
1667
- C: (f, a) => f(...a)
1668
- });
1669
- return false;
1670
- }
1671
- await this._feeds.process(credential, sourceFeed);
1672
- break;
1673
- }
1674
- case "dxos.halo.invitations.CancelDelegatedInvitation":
1675
- case "dxos.halo.invitations.DelegateSpaceInvitation": {
1676
- if (!this._canInviteNewMembers(credential.issuer)) {
1677
- import_log.log.warn(`Invalid invitation, space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
1678
- F: __dxlog_file6,
1679
- L: 222,
1680
- S: this,
1681
- C: (f, a) => f(...a)
1682
- });
1683
- return false;
1684
- }
1685
- await this._invitations.process(credential);
1686
- break;
1687
- }
1688
- }
1689
- const newEntry = {
1690
- credential,
1691
- sourceFeed,
1692
- revoked: false
1693
- };
1694
- this._credentials.push(newEntry);
1695
- if (credential.id) {
1696
- this._credentialsById.set(credential.id, newEntry);
1697
- }
1698
- for (const processor of this._credentialProcessors) {
1699
- if (processor._isReadyForLiveCredentials) {
1700
- await processor._process(credential);
1701
- }
1702
- }
1703
- await this.onCredentialProcessed.callIfSet(credential);
1704
- return true;
1705
- }
1706
- getMemberRole(memberKey) {
1707
- return this._members.getRole(memberKey);
1708
- }
1709
- hasMembershipManagementPermission(memberKey) {
1710
- return this._canInviteNewMembers(memberKey);
1711
- }
1712
- _canInviteNewMembers(key) {
1713
- return key.equals(this._spaceKey) || this._members.getRole(key) === import_credentials2.SpaceMember.Role.ADMIN || this._members.getRole(key) === import_credentials2.SpaceMember.Role.OWNER;
1714
- }
1715
- };
1716
- _ts_decorate([
1717
- import_async.synchronized
1718
- ], SpaceStateMachine.prototype, "process", null);
1719
- var CredentialConsumer = class {
1720
- constructor(processor, _onOpen, _onClose) {
1721
- this.processor = processor;
1722
- this._onOpen = _onOpen;
1723
- this._onClose = _onClose;
1724
- this._ctx = new import_context.Context(void 0, {
1725
- F: __dxlog_file6,
1726
- L: 267
1727
- });
1728
- this._isReadyForLiveCredentials = false;
1729
- }
1730
- /**
1731
- * @internal
1732
- */
1733
- async _process(credential) {
1734
- await (0, import_async.runInContextAsync)(this._ctx, async () => {
1735
- await this.processor.processCredential(credential);
1736
- });
1737
- }
1738
- async open() {
1739
- if (this._ctx.disposed) {
1740
- throw new Error("CredentialProcessor is disposed");
1741
- }
1742
- await this._onOpen();
1743
- }
1744
- async close() {
1745
- await this._ctx.dispose();
1746
- await this._onClose();
1747
- }
1748
- };
1749
- var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/processor/device-state-machine.ts";
1750
- var DeviceStateMachine = class {
1751
- constructor(_params) {
1752
- this._params = _params;
1753
- this.authorizedDeviceKeys = new import_util8.ComplexMap(import_keys9.PublicKey.hash);
1754
- this.deviceChainReady = new import_async2.Trigger();
1755
- }
1756
- async processCredential(credential) {
1757
- (0, import_log4.log)("processing credential...", {
1758
- identityKey: this._params.identityKey,
1759
- deviceKey: this._params.deviceKey,
1760
- credential
1761
- }, {
1762
- F: __dxlog_file7,
1763
- L: 35,
1764
- S: this,
1765
- C: (f, a) => f(...a)
1766
- });
1767
- if (isValidAuthorizedDeviceCredential(credential, this._params.identityKey, this._params.deviceKey)) {
1768
- this.deviceCredentialChain = {
1769
- credential
1770
- };
1771
- this.deviceChainReady.wake();
1772
- }
1773
- const assertion = getCredentialAssertion(credential);
1774
- switch (assertion["@type"]) {
1775
- case "dxos.halo.credentials.AuthorizedDevice": {
1776
- this.authorizedDeviceKeys.set(assertion.deviceKey, this.authorizedDeviceKeys.get(assertion.deviceKey) ?? {});
1777
- (0, import_log4.log)("added device", {
1778
- localDeviceKey: this._params.deviceKey,
1779
- deviceKey: assertion.deviceKey,
1780
- size: this.authorizedDeviceKeys.size
1781
- }, {
1782
- F: __dxlog_file7,
1783
- L: 55,
1784
- S: this,
1785
- C: (f, a) => f(...a)
1786
- });
1787
- this._params.onUpdate?.();
1788
- break;
1789
- }
1790
- case "dxos.halo.credentials.DeviceProfile": {
1791
- (0, import_invariant6.invariant)(this.authorizedDeviceKeys.has(credential.subject.id), "Device not found.", {
1792
- F: __dxlog_file7,
1793
- L: 65,
1794
- S: this,
1795
- A: [
1796
- "this.authorizedDeviceKeys.has(credential.subject.id)",
1797
- "'Device not found.'"
1798
- ]
1799
- });
1800
- if (assertion && credential.subject.id.equals(this._params.deviceKey)) {
1801
- import_log4.log.trace("dxos.halo.device", {
1802
- deviceKey: credential.subject.id,
1803
- profile: assertion.profile
1804
- }, {
1805
- F: __dxlog_file7,
1806
- L: 68,
1807
- S: this,
1808
- C: (f, a) => f(...a)
1809
- });
1810
- }
1811
- this.authorizedDeviceKeys.set(credential.subject.id, assertion.profile);
1812
- this._params.onUpdate?.();
1813
- break;
1814
- }
1815
- }
1816
- }
1817
- };
1818
- var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/processor/profile-state-machine.ts";
1819
- var ProfileStateMachine = class {
1820
- constructor(_params) {
1821
- this._params = _params;
1822
- }
1823
- async processCredential(credential) {
1824
- const assertion = getCredentialAssertion(credential);
1825
- switch (assertion["@type"]) {
1826
- case "dxos.halo.credentials.IdentityProfile": {
1827
- if (!credential.issuer.equals(this._params.identityKey) || !credential.subject.id.equals(this._params.identityKey)) {
1828
- import_log5.log.warn("Invalid profile credential", {
1829
- expectedIdentity: this._params.identityKey,
1830
- credential
1831
- }, {
1832
- F: __dxlog_file8,
1833
- L: 34,
1834
- S: this,
1835
- C: (f, a) => f(...a)
1836
- });
1837
- return;
1838
- }
1839
- this.profile = assertion.profile;
1840
- (0, import_log5.log)("updated profile", {
1841
- identityKey: this._params.identityKey,
1842
- profile: this.profile
1843
- }, {
1844
- F: __dxlog_file8,
1845
- L: 40,
1846
- S: this,
1847
- C: (f, a) => f(...a)
1848
- });
1849
- this._params.onUpdate?.();
1850
- break;
1851
- }
1852
- }
1853
- }
1854
- };
1855
- // Annotate the CommonJS export names for ESM import in node:
1856
- 0 && (module.exports = {
1857
- CredentialGenerator,
1858
- DeviceStateMachine,
1859
- FeedStateMachine,
1860
- InvitationStateMachine,
1861
- MemberStateMachine,
1862
- ProfileStateMachine,
1863
- SIGNATURE_TYPE_ED25519,
1864
- SpaceStateMachine,
1865
- canonicalStringify,
1866
- checkCredentialType,
1867
- createAdmissionCredentials,
1868
- createCancelDelegatedSpaceInvitationCredential,
1869
- createCredential,
1870
- createCredentialMessage,
1871
- createCredentialSignerWithChain,
1872
- createCredentialSignerWithKey,
1873
- createDelegatedSpaceInvitationCredential,
1874
- createDeviceAuthorization,
1875
- createDidFromIdentityKey,
1876
- credentialTypeFilter,
1877
- defaultSecretProvider,
1878
- defaultSecretValidator,
1879
- generatePasscode,
1880
- generateSeedPhrase,
1881
- getCredentialAssertion,
1882
- getCredentialProofPayload,
1883
- getPresentationProofPayload,
1884
- isValidAuthorizedDeviceCredential,
1885
- keyPairFromSeedPhrase,
1886
- signPresentation,
1887
- verifyChain,
1888
- verifyCredential,
1889
- verifyCredentialSignature,
1890
- verifyPresentation,
1891
- verifyPresentationChain,
1892
- verifyPresentationSignature
1893
- });
1894
- //# sourceMappingURL=index.cjs.map