@didcid/keymaster 0.3.8 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -234,11 +234,11 @@ keymaster list-ids
234
234
  | `create-asset` | Create empty asset |
235
235
  | `create-asset-json <file>` | Create from JSON file |
236
236
  | `create-asset-image <file>` | Create from image |
237
- | `create-asset-document <file>` | Create from document |
237
+ | `create-asset-file <file>` | Create from file |
238
238
  | `get-asset <id>` | Get asset by ID |
239
239
  | `update-asset-json <id> <file>` | Update with JSON |
240
240
  | `update-asset-image <id> <file>` | Update with image |
241
- | `update-asset-document <id> <file>` | Update with document |
241
+ | `update-asset-file <id> <file>` | Update with file |
242
242
  | `transfer-asset <id> <controller>` | Transfer ownership |
243
243
  | `clone-asset <id>` | Clone an asset |
244
244
  | `set-property <id> <key> [value]` | Set asset property |
@@ -388,7 +388,7 @@ class KeymasterClient {
388
388
  throwError(error);
389
389
  }
390
390
  }
391
- async updateAsset(id, data) {
391
+ async mergeData(id, data) {
392
392
  try {
393
393
  const response = await axios.put(`${this.API}/assets/${id}`, { data });
394
394
  return response.data.ok;
@@ -748,7 +748,7 @@ class KeymasterClient {
748
748
  headers: {
749
749
  // eslint-disable-next-line
750
750
  'Content-Type': 'application/octet-stream',
751
- 'X-Options': JSON.stringify(options), // Pass options as a custom header
751
+ 'X-Options': JSON.stringify(options),
752
752
  }
753
753
  });
754
754
  return response.data.did;
@@ -757,11 +757,12 @@ class KeymasterClient {
757
757
  throwError(error);
758
758
  }
759
759
  }
760
- async updateImage(id, data) {
760
+ async updateImage(id, data, options = {}) {
761
761
  try {
762
762
  const response = await axios.put(`${this.API}/images/${id}`, data, {
763
763
  headers: {
764
- 'Content-Type': 'application/octet-stream'
764
+ 'Content-Type': 'application/octet-stream',
765
+ 'X-Options': JSON.stringify(options),
765
766
  }
766
767
  });
767
768
  return response.data.ok;
@@ -773,7 +774,7 @@ class KeymasterClient {
773
774
  async getImage(id) {
774
775
  try {
775
776
  const response = await axios.get(`${this.API}/images/${id}`);
776
- return response.data.image;
777
+ return response.data;
777
778
  }
778
779
  catch (error) {
779
780
  throwError(error);
@@ -788,9 +789,9 @@ class KeymasterClient {
788
789
  throwError(error);
789
790
  }
790
791
  }
791
- async createDocument(data, options = {}) {
792
+ async createFile(data, options = {}) {
792
793
  try {
793
- const response = await axios.post(`${this.API}/documents`, data, {
794
+ const response = await axios.post(`${this.API}/files`, data, {
794
795
  headers: {
795
796
  'Content-Type': 'application/octet-stream',
796
797
  'X-Options': JSON.stringify(options), // Pass options as a custom header
@@ -802,9 +803,9 @@ class KeymasterClient {
802
803
  throwError(error);
803
804
  }
804
805
  }
805
- async updateDocument(id, data, options = {}) {
806
+ async updateFile(id, data, options = {}) {
806
807
  try {
807
- const response = await axios.put(`${this.API}/documents/${id}`, data, {
808
+ const response = await axios.put(`${this.API}/files/${id}`, data, {
808
809
  headers: {
809
810
  'Content-Type': 'application/octet-stream',
810
811
  'X-Options': JSON.stringify(options), // Pass options as a custom header
@@ -816,18 +817,18 @@ class KeymasterClient {
816
817
  throwError(error);
817
818
  }
818
819
  }
819
- async getDocument(id) {
820
+ async getFile(id) {
820
821
  try {
821
- const response = await axios.get(`${this.API}/documents/${id}`);
822
- return response.data.document;
822
+ const response = await axios.get(`${this.API}/files/${id}`);
823
+ return response.data.file;
823
824
  }
824
825
  catch (error) {
825
826
  throwError(error);
826
827
  }
827
828
  }
828
- async testDocument(id) {
829
+ async testFile(id) {
829
830
  try {
830
- const response = await axios.post(`${this.API}/documents/${id}/test`);
831
+ const response = await axios.post(`${this.API}/files/${id}/test`);
831
832
  return response.data.test;
832
833
  }
833
834
  catch (error) {
@@ -1658,7 +1658,7 @@ class Keymaster {
1658
1658
  const cloneData = { ...assetData, cloned: assetDoc.didDocument.id };
1659
1659
  return this.createAsset(cloneData, options);
1660
1660
  }
1661
- async generateImageAsset(buffer) {
1661
+ async generateImageAsset(filename, buffer) {
1662
1662
  let metadata;
1663
1663
  try {
1664
1664
  metadata = imageSize.imageSize(buffer);
@@ -1667,33 +1667,38 @@ class Keymaster {
1667
1667
  throw new InvalidParameterError('buffer');
1668
1668
  }
1669
1669
  const cid = await this.gatekeeper.addData(buffer);
1670
- const image = {
1670
+ const file = {
1671
1671
  cid,
1672
+ filename,
1673
+ type: `image/${metadata.type}`,
1672
1674
  bytes: buffer.length,
1673
- ...metadata,
1674
- type: `image/${metadata.type}`
1675
1675
  };
1676
- return image;
1676
+ const image = {
1677
+ width: metadata.width,
1678
+ height: metadata.height,
1679
+ };
1680
+ return { file, image };
1677
1681
  }
1678
1682
  async createImage(buffer, options = {}) {
1679
- const image = await this.generateImageAsset(buffer);
1680
- return this.createAsset({ image }, options);
1683
+ const filename = options.filename || 'image';
1684
+ const { file, image } = await this.generateImageAsset(filename, buffer);
1685
+ return this.createAsset({ file, image }, options);
1681
1686
  }
1682
- async updateImage(id, buffer) {
1683
- const image = await this.generateImageAsset(buffer);
1684
- return this.updateAsset(id, { image });
1687
+ async updateImage(id, buffer, options = {}) {
1688
+ const filename = options.filename || 'image';
1689
+ const { file, image } = await this.generateImageAsset(filename, buffer);
1690
+ return this.mergeData(id, { file, image });
1685
1691
  }
1686
1692
  async getImage(id) {
1687
1693
  const asset = await this.resolveAsset(id);
1688
- const image = asset.image;
1689
- if (!image || !image.cid) {
1694
+ if (!asset.file || !asset.file.cid || !asset.image) {
1690
1695
  return null;
1691
1696
  }
1692
- const buffer = await this.gatekeeper.getData(image.cid);
1697
+ const buffer = await this.gatekeeper.getData(asset.file.cid);
1693
1698
  if (buffer) {
1694
- image.data = buffer;
1699
+ asset.file.data = buffer;
1695
1700
  }
1696
- return image;
1701
+ return { file: asset.file, image: asset.image };
1697
1702
  }
1698
1703
  async testImage(id) {
1699
1704
  try {
@@ -1736,24 +1741,32 @@ class Keymaster {
1736
1741
  };
1737
1742
  return file;
1738
1743
  }
1739
- async createDocument(buffer, options = {}) {
1740
- const filename = options.filename || 'document';
1741
- const document = await this.generateFileAsset(filename, buffer);
1742
- return this.createAsset({ document }, options);
1744
+ async createFile(buffer, options = {}) {
1745
+ const filename = options.filename || 'file';
1746
+ const file = await this.generateFileAsset(filename, buffer);
1747
+ return this.createAsset({ file }, options);
1743
1748
  }
1744
- async updateDocument(id, buffer, options = {}) {
1745
- const filename = options.filename || 'document';
1746
- const document = await this.generateFileAsset(filename, buffer);
1747
- return this.updateAsset(id, { document });
1749
+ async updateFile(id, buffer, options = {}) {
1750
+ const filename = options.filename || 'file';
1751
+ const file = await this.generateFileAsset(filename, buffer);
1752
+ return this.mergeData(id, { file });
1748
1753
  }
1749
- async getDocument(id) {
1754
+ async getFile(id) {
1750
1755
  const asset = await this.resolveAsset(id);
1751
- return asset.document ?? null;
1756
+ const file = asset.file;
1757
+ if (!file || !file.cid) {
1758
+ return null;
1759
+ }
1760
+ const buffer = await this.gatekeeper.getData(file.cid);
1761
+ if (buffer) {
1762
+ file.data = buffer;
1763
+ }
1764
+ return file;
1752
1765
  }
1753
- async testDocument(id) {
1766
+ async testFile(id) {
1754
1767
  try {
1755
- const document = await this.getDocument(id);
1756
- return document !== null;
1768
+ const file = await this.getFile(id);
1769
+ return file !== null;
1757
1770
  }
1758
1771
  catch (error) {
1759
1772
  return false;
@@ -2037,13 +2050,14 @@ class Keymaster {
2037
2050
  }
2038
2051
  return doc.didDocumentData;
2039
2052
  }
2040
- async updateAsset(did, data) {
2053
+ async mergeData(did, data) {
2041
2054
  const doc = await this.resolveDID(did);
2042
2055
  const currentData = doc.didDocumentData || {};
2043
- const updatedData = {
2044
- ...currentData,
2045
- ...data
2046
- };
2056
+ const updatedData = { ...currentData, ...data };
2057
+ for (const key of Object.keys(updatedData)) {
2058
+ if (updatedData[key] === null)
2059
+ delete updatedData[key];
2060
+ }
2047
2061
  return this.updateDID(did, { didDocumentData: updatedData });
2048
2062
  }
2049
2063
  async transferAsset(id, controller) {
@@ -2761,7 +2775,7 @@ class Keymaster {
2761
2775
  const members = new Set(group.members);
2762
2776
  members.add(memberDID);
2763
2777
  group.members = Array.from(members);
2764
- return this.updateAsset(groupDID, { group });
2778
+ return this.mergeData(groupDID, { group });
2765
2779
  }
2766
2780
  async removeGroupMember(groupId, memberId) {
2767
2781
  const groupDID = await this.lookupDID(groupId);
@@ -2784,7 +2798,7 @@ class Keymaster {
2784
2798
  const members = new Set(group.members);
2785
2799
  members.delete(memberDID);
2786
2800
  group.members = Array.from(members);
2787
- return this.updateAsset(groupDID, { group });
2801
+ return this.mergeData(groupDID, { group });
2788
2802
  }
2789
2803
  async testGroup(groupId, memberId) {
2790
2804
  try {
@@ -2875,7 +2889,7 @@ class Keymaster {
2875
2889
  if (!this.validateSchema(schema)) {
2876
2890
  throw new InvalidParameterError('schema');
2877
2891
  }
2878
- return this.updateAsset(id, { schema });
2892
+ return this.mergeData(id, { schema });
2879
2893
  }
2880
2894
  // TBD add optional 2nd parameter that will validate JSON against the schema
2881
2895
  async testSchema(id) {
@@ -3151,7 +3165,7 @@ class Keymaster {
3151
3165
  ballot: didBallot,
3152
3166
  received: new Date().toISOString(),
3153
3167
  };
3154
- return this.updateAsset(didPoll, { poll });
3168
+ return this.mergeData(didPoll, { poll });
3155
3169
  }
3156
3170
  async publishPoll(pollId, options = {}) {
3157
3171
  const { reveal = false } = options;
@@ -3173,7 +3187,7 @@ class Keymaster {
3173
3187
  throw new InvalidParameterError(pollId);
3174
3188
  }
3175
3189
  poll.results = view.results;
3176
- return this.updateAsset(pollId, { poll });
3190
+ return this.mergeData(pollId, { poll });
3177
3191
  }
3178
3192
  async unpublishPoll(pollId) {
3179
3193
  const id = await this.fetchIdInfo();
@@ -3187,7 +3201,7 @@ class Keymaster {
3187
3201
  throw new InvalidParameterError(pollId);
3188
3202
  }
3189
3203
  delete poll.results;
3190
- return this.updateAsset(pollId, { poll });
3204
+ return this.mergeData(pollId, { poll });
3191
3205
  }
3192
3206
  async createVault(options = {}) {
3193
3207
  const id = await this.fetchIdInfo();
@@ -3316,7 +3330,7 @@ class Keymaster {
3316
3330
  for (const memberDID of Object.keys(members)) {
3317
3331
  await this.addMemberKey(vault, memberDID, privateJwk);
3318
3332
  }
3319
- await this.updateAsset(vaultId, { vault });
3333
+ await this.mergeData(vaultId, { vault });
3320
3334
  return;
3321
3335
  }
3322
3336
  throw new KeymasterError('Unsupported vault version');
@@ -3346,7 +3360,7 @@ class Keymaster {
3346
3360
  const publicJwk = config.secretMembers ? idKeypair.publicJwk : vault.publicJwk;
3347
3361
  vault.members = this.cipher.encryptMessage(publicJwk, privateJwk, JSON.stringify(members));
3348
3362
  await this.addMemberKey(vault, memberDID, privateJwk);
3349
- return this.updateAsset(vaultId, { vault });
3363
+ return this.mergeData(vaultId, { vault });
3350
3364
  }
3351
3365
  async removeVaultMember(vaultId, memberId) {
3352
3366
  const owner = await this.checkVaultOwner(vaultId);
@@ -3364,7 +3378,7 @@ class Keymaster {
3364
3378
  vault.members = this.cipher.encryptMessage(publicJwk, privateJwk, JSON.stringify(members));
3365
3379
  const memberKeyId = this.generateSaltedId(vault, memberDID);
3366
3380
  delete vault.keys[memberKeyId];
3367
- return this.updateAsset(vaultId, { vault });
3381
+ return this.mergeData(vaultId, { vault });
3368
3382
  }
3369
3383
  async listVaultMembers(vaultId) {
3370
3384
  const vault = await this.getVault(vaultId);
@@ -3394,7 +3408,7 @@ class Keymaster {
3394
3408
  };
3395
3409
  vault.items = this.cipher.encryptMessage(vault.publicJwk, privateJwk, JSON.stringify(items));
3396
3410
  vault.sha256 = this.cipher.hashJSON(items);
3397
- return this.updateAsset(vaultId, { vault });
3411
+ return this.mergeData(vaultId, { vault });
3398
3412
  }
3399
3413
  async removeVaultItem(vaultId, name) {
3400
3414
  await this.checkVaultOwner(vaultId);
@@ -3403,7 +3417,7 @@ class Keymaster {
3403
3417
  delete items[name];
3404
3418
  vault.items = this.cipher.encryptMessage(vault.publicJwk, privateJwk, JSON.stringify(items));
3405
3419
  vault.sha256 = this.cipher.hashJSON(items);
3406
- return this.updateAsset(vaultId, { vault });
3420
+ return this.mergeData(vaultId, { vault });
3407
3421
  }
3408
3422
  async listVaultItems(vaultId, options) {
3409
3423
  const vault = await this.getVault(vaultId, options);
@@ -3654,7 +3668,7 @@ class Keymaster {
3654
3668
  }
3655
3669
  async updateNotice(id, message) {
3656
3670
  const notice = await this.verifyNotice(message);
3657
- return this.updateAsset(id, { notice });
3671
+ return this.mergeData(id, { notice });
3658
3672
  }
3659
3673
  async addToNotices(did, tags) {
3660
3674
  const verifiedTags = this.verifyTagList(tags);
package/dist/esm/cli.js CHANGED
@@ -827,7 +827,8 @@ program
827
827
  try {
828
828
  const { alias, registry } = options;
829
829
  const data = fs.readFileSync(file);
830
- const did = await keymaster.createImage(data, { alias, registry });
830
+ const filename = path.basename(file);
831
+ const did = await keymaster.createImage(data, { filename, alias, registry });
831
832
  console.log(did);
832
833
  }
833
834
  catch (error) {
@@ -835,8 +836,8 @@ program
835
836
  }
836
837
  });
837
838
  program
838
- .command('create-asset-document <file>')
839
- .description('Create an asset from a document file')
839
+ .command('create-asset-file <file>')
840
+ .description('Create an asset from a file')
840
841
  .option('-a, --alias <alias>', 'DID alias')
841
842
  .option('-r, --registry <registry>', 'registry to use')
842
843
  .action(async (file, options) => {
@@ -844,7 +845,7 @@ program
844
845
  const { alias, registry } = options;
845
846
  const data = fs.readFileSync(file);
846
847
  const filename = path.basename(file);
847
- const did = await keymaster.createDocument(data, { filename, alias, registry });
848
+ const did = await keymaster.createFile(data, { filename, alias, registry });
848
849
  console.log(did);
849
850
  }
850
851
  catch (error) {
@@ -863,13 +864,62 @@ program
863
864
  console.error(error.error || error.message || error);
864
865
  }
865
866
  });
867
+ program
868
+ .command('get-asset-json <id> <file>')
869
+ .description('Save a JSON asset to a file')
870
+ .action(async (id, file) => {
871
+ try {
872
+ const asset = await keymaster.resolveAsset(id);
873
+ fs.writeFileSync(file, JSON.stringify(asset, null, 4));
874
+ console.log(`Data written to ${file}`);
875
+ }
876
+ catch (error) {
877
+ console.error(error.error || error.message || error);
878
+ }
879
+ });
880
+ program
881
+ .command('get-asset-image <id> [file]')
882
+ .description('Save an image asset to a file')
883
+ .action(async (id, file) => {
884
+ try {
885
+ const imageAsset = await keymaster.getImage(id);
886
+ if (!imageAsset || !imageAsset.file.data) {
887
+ console.error('Image not found');
888
+ return;
889
+ }
890
+ const outputFile = file || imageAsset.file.filename;
891
+ fs.writeFileSync(outputFile, imageAsset.file.data);
892
+ console.log(`Data written to ${outputFile}`);
893
+ }
894
+ catch (error) {
895
+ console.error(error.error || error.message || error);
896
+ }
897
+ });
898
+ program
899
+ .command('get-asset-file <id> [file]')
900
+ .description('Save a file asset to a file')
901
+ .action(async (id, file) => {
902
+ try {
903
+ const fileAsset = await keymaster.getFile(id);
904
+ if (!fileAsset || !fileAsset.data) {
905
+ console.error('File not found');
906
+ return;
907
+ }
908
+ const outputFile = file || fileAsset.filename;
909
+ fs.writeFileSync(outputFile, fileAsset.data);
910
+ console.log(`Data written to ${outputFile}`);
911
+ }
912
+ catch (error) {
913
+ console.error(error.error || error.message || error);
914
+ }
915
+ });
866
916
  program
867
917
  .command('update-asset-json <id> <file>')
868
918
  .description('Update an asset from a JSON file')
869
919
  .action(async (id, file) => {
870
920
  try {
871
921
  const data = JSON.parse(fs.readFileSync(file).toString());
872
- const ok = await keymaster.updateAsset(id, data);
922
+ const ok = await keymaster.mergeData(id, data);
873
923
  console.log(ok ? UPDATE_OK : UPDATE_FAILED);
874
924
  }
875
925
  catch (error) {
@@ -882,7 +932,8 @@ program
882
932
  .action(async (id, file) => {
883
933
  try {
884
934
  const data = fs.readFileSync(file);
885
- const ok = await keymaster.updateImage(id, data);
935
+ const filename = path.basename(file);
936
+ const ok = await keymaster.updateImage(id, data, { filename });
886
937
  console.log(ok ? UPDATE_OK : UPDATE_FAILED);
887
938
  }
888
939
  catch (error) {
@@ -890,13 +941,13 @@ program
890
941
  }
891
942
  });
892
943
  program
893
- .command('update-asset-document <id> <file>')
894
- .description('Update an asset from a document file')
944
+ .command('update-asset-file <id> <file>')
945
+ .description('Update an asset from a file')
895
946
  .action(async (id, file) => {
896
947
  try {
897
948
  const data = fs.readFileSync(file);
898
949
  const filename = path.basename(file);
899
- const ok = await keymaster.updateDocument(id, data, { filename });
950
+ const ok = await keymaster.updateFile(id, data, { filename });
900
951
  console.log(ok ? UPDATE_OK : UPDATE_FAILED);
901
952
  }
902
953
  catch (error) {
@@ -930,24 +981,37 @@ program
930
981
  console.error(error.error || error.message || error);
931
982
  }
932
983
  });
984
+ program
985
+ .command('get-property <id> <key>')
986
+ .description('Get a property value from a DID')
987
+ .action(async (id, key) => {
988
+ try {
989
+ const doc = await keymaster.resolveDID(id);
990
+ const data = doc.didDocumentData || {};
991
+ const value = data[key];
992
+ if (value !== undefined) {
993
+ console.log(JSON.stringify(value, null, 4));
994
+ }
995
+ }
996
+ catch (error) {
997
+ console.error(error.error || error.message || error);
998
+ }
999
+ });
933
1000
  program
934
1001
  .command('set-property <id> <key> [value]')
935
- .description('Assign a key-value pair to an asset')
1002
+ .description('Assign a key-value pair to a DID')
936
1003
  .action(async (id, key, value) => {
937
1004
  try {
938
- const data = await keymaster.resolveAsset(id);
1005
+ let parsed = null;
939
1006
  if (value) {
940
1007
  try {
941
- data[key] = JSON.parse(value);
1008
+ parsed = JSON.parse(value);
942
1009
  }
943
1010
  catch {
944
- data[key] = value;
1011
+ parsed = value;
945
1012
  }
946
1013
  }
947
- else {
948
- delete data[key];
949
- }
950
- const ok = await keymaster.updateAsset(id, data);
1014
+ const ok = await keymaster.mergeData(id, { [key]: parsed });
951
1015
  console.log(ok ? UPDATE_OK : UPDATE_FAILED);
952
1016
  }
953
1017
  catch (error) {
@@ -1290,7 +1354,7 @@ program
1290
1354
  });
1291
1355
  program
1292
1356
  .command('remove-dmail <did>')
1293
- .description('Remove a dmail from inbox')
1357
+ .description('Delete a dmail')
1294
1358
  .action(async (did) => {
1295
1359
  try {
1296
1360
  const ok = await keymaster.removeDmail(did);