@dxos/credentials 0.4.10-next.71cec10 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,6 +31,7 @@ __export(node_exports, {
31
31
  CredentialGenerator: () => CredentialGenerator,
32
32
  DeviceStateMachine: () => DeviceStateMachine,
33
33
  FeedStateMachine: () => FeedStateMachine,
34
+ InvitationStateMachine: () => InvitationStateMachine,
34
35
  MemberStateMachine: () => MemberStateMachine,
35
36
  ProfileStateMachine: () => ProfileStateMachine,
36
37
  SIGNATURE_TYPE_ED25519: () => SIGNATURE_TYPE_ED25519,
@@ -42,6 +43,7 @@ __export(node_exports, {
42
43
  createCredentialMessage: () => createCredentialMessage,
43
44
  createCredentialSignerWithChain: () => createCredentialSignerWithChain,
44
45
  createCredentialSignerWithKey: () => createCredentialSignerWithKey,
46
+ createDelegatedSpaceInvitationCredential: () => createDelegatedSpaceInvitationCredential,
45
47
  createDeviceAuthorization: () => createDeviceAuthorization,
46
48
  credentialTypeFilter: () => credentialTypeFilter,
47
49
  defaultSecretProvider: () => defaultSecretProvider,
@@ -80,15 +82,17 @@ var import_util2 = require("@dxos/util");
80
82
  var import_invariant2 = require("@dxos/invariant");
81
83
  var import_keys4 = require("@dxos/keys");
82
84
  var import_util3 = require("@dxos/util");
83
- var import_invariant3 = require("@dxos/invariant");
84
85
  var import_keys5 = require("@dxos/keys");
85
- var import_log2 = require("@dxos/log");
86
86
  var import_util4 = require("@dxos/util");
87
+ var import_invariant3 = require("@dxos/invariant");
88
+ var import_keys6 = require("@dxos/keys");
89
+ var import_log2 = require("@dxos/log");
90
+ var import_util5 = require("@dxos/util");
87
91
  var import_async2 = require("@dxos/async");
88
92
  var import_invariant4 = require("@dxos/invariant");
89
- var import_keys6 = require("@dxos/keys");
93
+ var import_keys7 = require("@dxos/keys");
90
94
  var import_log3 = require("@dxos/log");
91
- var import_util5 = require("@dxos/util");
95
+ var import_util6 = require("@dxos/util");
92
96
  var import_log4 = require("@dxos/log");
93
97
  var defaultSecretProvider = async () => Buffer.from("0000");
94
98
  var defaultSecretValidator = async (invitation, secret) => true;
@@ -462,7 +466,7 @@ var createDeviceAuthorization = async (signer, identityKey, deviceKey) => {
462
466
  credential
463
467
  }));
464
468
  };
465
- var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFeedKey, profile) => {
469
+ var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFeedKey, profile, invitationCredentialId) => {
466
470
  const credentials = await Promise.all([
467
471
  await signer.createCredential({
468
472
  subject: identityKey,
@@ -471,7 +475,8 @@ var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFe
471
475
  spaceKey,
472
476
  role: import_credentials.SpaceMember.Role.ADMIN,
473
477
  profile,
474
- genesisFeedKey
478
+ genesisFeedKey,
479
+ invitationCredentialId
475
480
  }
476
481
  })
477
482
  ]);
@@ -481,6 +486,26 @@ var createAdmissionCredentials = async (signer, identityKey, spaceKey, genesisFe
481
486
  }
482
487
  }));
483
488
  };
489
+ var createDelegatedSpaceInvitationCredential = async (signer, subject, invitation) => {
490
+ const credential = await signer.createCredential({
491
+ subject,
492
+ assertion: {
493
+ "@type": "dxos.halo.invitations.DelegateSpaceInvitation",
494
+ invitationId: invitation.invitationId,
495
+ authMethod: invitation.authMethod,
496
+ swarmKey: invitation.swarmKey,
497
+ role: invitation.role,
498
+ guestKey: invitation.guestKey,
499
+ expiresOn: invitation.expiresOn,
500
+ multiUse: invitation.multiUse
501
+ }
502
+ });
503
+ return {
504
+ credential: {
505
+ credential
506
+ }
507
+ };
508
+ };
484
509
  var signPresentation = async ({ presentation, signer, signerKey, chain, nonce }) => {
485
510
  const proof = {
486
511
  type: SIGNATURE_TYPE_ED25519,
@@ -629,12 +654,78 @@ var FeedStateMachine = class {
629
654
  await this.onFeedAdmitted.callIfSet(info);
630
655
  }
631
656
  };
657
+ var InvitationStateMachine = class {
658
+ constructor() {
659
+ this._invitations = new import_util4.ComplexMap(import_keys5.PublicKey.hash);
660
+ this._redeemedInvitationCredentialIds = new import_util4.ComplexSet(import_keys5.PublicKey.hash);
661
+ this._cancelledInvitationCredentialIds = new import_util4.ComplexSet(import_keys5.PublicKey.hash);
662
+ this.onDelegatedInvitation = new import_util4.Callback();
663
+ this.onDelegatedInvitationRemoved = new import_util4.Callback();
664
+ }
665
+ get invitations() {
666
+ return this._invitations;
667
+ }
668
+ async process(credential) {
669
+ const credentialId = credential.id;
670
+ if (credentialId == null) {
671
+ return;
672
+ }
673
+ const assertion = getCredentialAssertion(credential);
674
+ switch (assertion["@type"]) {
675
+ case "dxos.halo.invitations.CancelDelegatedInvitation": {
676
+ this._cancelledInvitationCredentialIds.add(assertion.credentialId);
677
+ const existingInvitation = this._invitations.get(assertion.credentialId);
678
+ if (existingInvitation != null) {
679
+ this._invitations.delete(assertion.credentialId);
680
+ await this.onDelegatedInvitationRemoved.callIfSet({
681
+ credentialId: assertion.credentialId,
682
+ invitation: existingInvitation
683
+ });
684
+ }
685
+ break;
686
+ }
687
+ case "dxos.halo.invitations.DelegateSpaceInvitation": {
688
+ if (credential.id) {
689
+ const isExpired = assertion.expiresOn && assertion.expiresOn.getTime() < Date.now();
690
+ const wasUsed = this._redeemedInvitationCredentialIds.has(credential.id) && !assertion.multiUse;
691
+ const wasCancelled = this._cancelledInvitationCredentialIds.has(credential.id);
692
+ if (isExpired || wasCancelled || wasUsed) {
693
+ return;
694
+ }
695
+ const invitation = {
696
+ ...assertion
697
+ };
698
+ this._invitations.set(credential.id, invitation);
699
+ await this.onDelegatedInvitation.callIfSet({
700
+ credentialId: credential.id,
701
+ invitation
702
+ });
703
+ }
704
+ break;
705
+ }
706
+ case "dxos.halo.credentials.SpaceMember": {
707
+ if (assertion.invitationCredentialId != null) {
708
+ this._redeemedInvitationCredentialIds.add(assertion.invitationCredentialId);
709
+ const existingInvitation = this._invitations.get(assertion.invitationCredentialId);
710
+ if (existingInvitation != null && !existingInvitation.multiUse) {
711
+ this._invitations.delete(assertion.invitationCredentialId);
712
+ await this.onDelegatedInvitationRemoved.callIfSet({
713
+ credentialId: assertion.invitationCredentialId,
714
+ invitation: existingInvitation
715
+ });
716
+ }
717
+ }
718
+ break;
719
+ }
720
+ }
721
+ }
722
+ };
632
723
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/state-machine/member-state-machine.ts";
633
724
  var MemberStateMachine = class {
634
725
  constructor(_spaceKey) {
635
726
  this._spaceKey = _spaceKey;
636
- this._members = new import_util4.ComplexMap(import_keys5.PublicKey.hash);
637
- this.onMemberAdmitted = new import_util4.Callback();
727
+ this._members = new import_util5.ComplexMap(import_keys6.PublicKey.hash);
728
+ this.onMemberAdmitted = new import_util5.Callback();
638
729
  }
639
730
  get creator() {
640
731
  return this._creator;
@@ -729,7 +820,7 @@ var MemberStateMachine = class {
729
820
  }
730
821
  };
731
822
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/src/state-machine/space-state-machine.ts";
732
- var REVOKABLE_CREDENTIALS = [
823
+ var REVOCABLE_CREDENTIALS = [
733
824
  "dxos.halo.credentials.SpaceMember"
734
825
  ];
735
826
  var SpaceStateMachine = class {
@@ -737,6 +828,7 @@ var SpaceStateMachine = class {
737
828
  this._spaceKey = _spaceKey;
738
829
  this._members = new MemberStateMachine(this._spaceKey);
739
830
  this._feeds = new FeedStateMachine(this._spaceKey);
831
+ this._invitations = new InvitationStateMachine();
740
832
  this._credentials = [];
741
833
  this._credentialsById = new import_util2.ComplexMap(import_keys3.PublicKey.hash);
742
834
  this._processedCredentials = new import_util2.ComplexSet(import_keys3.PublicKey.hash);
@@ -744,6 +836,8 @@ var SpaceStateMachine = class {
744
836
  this.onCredentialProcessed = new import_util2.Callback();
745
837
  this.onMemberAdmitted = this._members.onMemberAdmitted;
746
838
  this.onFeedAdmitted = this._feeds.onFeedAdmitted;
839
+ this.onDelegatedInvitation = this._invitations.onDelegatedInvitation;
840
+ this.onDelegatedInvitationRemoved = this._invitations.onDelegatedInvitationRemoved;
747
841
  }
748
842
  get creator() {
749
843
  return this._members.creator;
@@ -763,6 +857,9 @@ var SpaceStateMachine = class {
763
857
  get genesisCredential() {
764
858
  return this._genesisCredential;
765
859
  }
860
+ get invitations() {
861
+ return this._invitations.invitations;
862
+ }
766
863
  async addCredentialProcessor(processor) {
767
864
  if (this._credentialProcessors.find((p) => p.processor === processor)) {
768
865
  throw new Error("Credential processor already added.");
@@ -801,7 +898,7 @@ var SpaceStateMachine = class {
801
898
  if (result.kind !== "pass") {
802
899
  import_log.log.warn(`Invalid credential: ${result.errors.join(", ")}`, void 0, {
803
900
  F: __dxlog_file4,
804
- L: 139,
901
+ L: 149,
805
902
  S: this,
806
903
  C: (f, a) => f(...a)
807
904
  });
@@ -814,7 +911,7 @@ var SpaceStateMachine = class {
814
911
  if (!this._canRevokeCredentials(credential.issuer)) {
815
912
  import_log.log.warn(`Space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
816
913
  F: __dxlog_file4,
817
- L: 148,
914
+ L: 158,
818
915
  S: this,
819
916
  C: (f, a) => f(...a)
820
917
  });
@@ -824,7 +921,7 @@ var SpaceStateMachine = class {
824
921
  if (!toBeRevoked) {
825
922
  import_log.log.warn(`Credential to revoke not found: ${credential.subject.id}`, void 0, {
826
923
  F: __dxlog_file4,
827
- L: 153,
924
+ L: 163,
828
925
  S: this,
829
926
  C: (f, a) => f(...a)
830
927
  });
@@ -833,7 +930,7 @@ var SpaceStateMachine = class {
833
930
  if (!this._credentialCanBeRevoked(toBeRevoked)) {
834
931
  import_log.log.warn(`Credential cannot be revoked: ${credential.subject.id}`, void 0, {
835
932
  F: __dxlog_file4,
836
- L: 157,
933
+ L: 167,
837
934
  S: this,
838
935
  C: (f, a) => f(...a)
839
936
  });
@@ -846,7 +943,7 @@ var SpaceStateMachine = class {
846
943
  if (this._genesisCredential) {
847
944
  import_log.log.warn("Space already has a genesis credential.", void 0, {
848
945
  F: __dxlog_file4,
849
- L: 167,
946
+ L: 176,
850
947
  S: this,
851
948
  C: (f, a) => f(...a)
852
949
  });
@@ -855,7 +952,7 @@ var SpaceStateMachine = class {
855
952
  if (!credential.issuer.equals(this._spaceKey)) {
856
953
  import_log.log.warn("Space genesis credential must be issued by space.", void 0, {
857
954
  F: __dxlog_file4,
858
- L: 171,
955
+ L: 180,
859
956
  S: this,
860
957
  C: (f, a) => f(...a)
861
958
  });
@@ -864,7 +961,7 @@ var SpaceStateMachine = class {
864
961
  if (!credential.subject.id.equals(this._spaceKey)) {
865
962
  import_log.log.warn("Space genesis credential must be issued to space.", void 0, {
866
963
  F: __dxlog_file4,
867
- L: 175,
964
+ L: 184,
868
965
  S: this,
869
966
  C: (f, a) => f(...a)
870
967
  });
@@ -880,7 +977,7 @@ var SpaceStateMachine = class {
880
977
  if (!this._genesisCredential) {
881
978
  import_log.log.warn("Space must have a genesis credential before adding members.", void 0, {
882
979
  F: __dxlog_file4,
883
- L: 189,
980
+ L: 198,
884
981
  S: this,
885
982
  C: (f, a) => f(...a)
886
983
  });
@@ -889,20 +986,21 @@ var SpaceStateMachine = class {
889
986
  if (!this._canInviteNewMembers(credential.issuer)) {
890
987
  import_log.log.warn(`Space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
891
988
  F: __dxlog_file4,
892
- L: 193,
989
+ L: 202,
893
990
  S: this,
894
991
  C: (f, a) => f(...a)
895
992
  });
896
993
  return false;
897
994
  }
898
995
  await this._members.process(credential);
996
+ await this._invitations.process(credential);
899
997
  break;
900
998
  }
901
999
  case "dxos.halo.credentials.MemberProfile": {
902
1000
  if (!this._genesisCredential) {
903
1001
  import_log.log.warn("Space must have a genesis credential before adding members.", void 0, {
904
1002
  F: __dxlog_file4,
905
- L: 203,
1003
+ L: 213,
906
1004
  S: this,
907
1005
  C: (f, a) => f(...a)
908
1006
  });
@@ -915,7 +1013,7 @@ var SpaceStateMachine = class {
915
1013
  if (!this._genesisCredential) {
916
1014
  import_log.log.warn("Space must have a genesis credential before admitting feeds.", void 0, {
917
1015
  F: __dxlog_file4,
918
- L: 213,
1016
+ L: 223,
919
1017
  S: this,
920
1018
  C: (f, a) => f(...a)
921
1019
  });
@@ -924,7 +1022,7 @@ var SpaceStateMachine = class {
924
1022
  if (!this._canAdmitFeeds(credential.issuer)) {
925
1023
  import_log.log.warn(`Space member is not authorized to admit feeds: ${credential.issuer}`, void 0, {
926
1024
  F: __dxlog_file4,
927
- L: 217,
1025
+ L: 227,
928
1026
  S: this,
929
1027
  C: (f, a) => f(...a)
930
1028
  });
@@ -933,6 +1031,20 @@ var SpaceStateMachine = class {
933
1031
  await this._feeds.process(credential, sourceFeed);
934
1032
  break;
935
1033
  }
1034
+ case "dxos.halo.invitations.CancelDelegatedInvitation":
1035
+ case "dxos.halo.invitations.DelegateSpaceInvitation": {
1036
+ if (!this._canInviteNewMembers(credential.issuer)) {
1037
+ import_log.log.warn(`Invalid invitation, space member is not authorized to invite new members: ${credential.issuer}`, void 0, {
1038
+ F: __dxlog_file4,
1039
+ L: 238,
1040
+ S: this,
1041
+ C: (f, a) => f(...a)
1042
+ });
1043
+ return false;
1044
+ }
1045
+ await this._invitations.process(credential);
1046
+ break;
1047
+ }
936
1048
  }
937
1049
  const newEntry = {
938
1050
  credential,
@@ -962,7 +1074,7 @@ var SpaceStateMachine = class {
962
1074
  return key.equals(this._spaceKey) || this._members.getRole(key) === import_credentials2.SpaceMember.Role.ADMIN;
963
1075
  }
964
1076
  _credentialCanBeRevoked(entry) {
965
- return REVOKABLE_CREDENTIALS.includes(entry.credential.subject.assertion["@type"]);
1077
+ return REVOCABLE_CREDENTIALS.includes(entry.credential.subject.assertion["@type"]);
966
1078
  }
967
1079
  };
968
1080
  var CredentialConsumer = class {
@@ -996,7 +1108,7 @@ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/halo/credentials/
996
1108
  var DeviceStateMachine = class {
997
1109
  constructor(_params) {
998
1110
  this._params = _params;
999
- this.authorizedDeviceKeys = new import_util5.ComplexMap(import_keys6.PublicKey.hash);
1111
+ this.authorizedDeviceKeys = new import_util6.ComplexMap(import_keys7.PublicKey.hash);
1000
1112
  this.deviceChainReady = new import_async2.Trigger();
1001
1113
  }
1002
1114
  async processCredential(credential) {
@@ -1112,6 +1224,7 @@ var ProfileStateMachine = class {
1112
1224
  CredentialGenerator,
1113
1225
  DeviceStateMachine,
1114
1226
  FeedStateMachine,
1227
+ InvitationStateMachine,
1115
1228
  MemberStateMachine,
1116
1229
  ProfileStateMachine,
1117
1230
  SIGNATURE_TYPE_ED25519,
@@ -1123,6 +1236,7 @@ var ProfileStateMachine = class {
1123
1236
  createCredentialMessage,
1124
1237
  createCredentialSignerWithChain,
1125
1238
  createCredentialSignerWithKey,
1239
+ createDelegatedSpaceInvitationCredential,
1126
1240
  createDeviceAuthorization,
1127
1241
  credentialTypeFilter,
1128
1242
  defaultSecretProvider,