@eluvio/elv-client-js 4.2.27 → 4.2.30

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/src/ElvClient.js CHANGED
@@ -936,6 +936,57 @@ class ElvClient {
936
936
  json 79b {"adr":"VVf4DQU357tDnZGYQeDrntRJ5rs=","spc":"ispc3ANoVSzNA3P6t7abLR69ho5YPPZU"}
937
937
  */
938
938
 
939
+ /*
940
+ PLAIN TOKEN PREFIX + BODY | aplsjcJf1HYcDDUuCdXcSZtU86nYK162YmYJeuqwMczEBJVkD5D5EvsBvVwYDRsf4hzDvBWMoe9piBpqx...
941
+ PREFIX 6b aplsjc | apl=plain s=ES256K jc=json-compressed
942
+ BODY base58(SIGNATURE + PAYLOAD)
943
+ SIGNATURE 65b ES256K signature
944
+ PAYLOAD raw-deflate JSON
945
+ json {"adr":"VVf4DQU357tDnZGYQeDrntRJ5rs=","spc":"ispc3ANoVSzNA3P6t7abLR69ho5YPPZU"}
946
+ */
947
+
948
+ /**
949
+ * Create a signed "plain" authorization token (`aplsjc...`).
950
+ *
951
+ * Plain tokens are largely the same as client-signed access tokens - they do not contain a b/c transaction
952
+ * and authorization is determined from the rights of the current signer's address.
953
+ * Currently needed for tenant content query /tenant/:tid/q/query
954
+ * This token will be deprecated in the future in favor of client-signed access tokens.
955
+ *
956
+ * @methodGroup Authorization
957
+ * @namedParams
958
+ * @param {string=} libraryId - Optional library ID to scope the token. If omitted, the token is space-wide.
959
+ * @returns {Promise<string>} - The signed Plain auth token
960
+ */
961
+ async CreatePlainToken({libraryId}={}) {
962
+ const address = this.CurrentAccountAddress();
963
+ if(!address) {
964
+ throw Error("Unable to create plain token: No signer is configured");
965
+ }
966
+
967
+ const token = {
968
+ adr: Buffer.from(address.replace(/^0x/, ""), "hex").toString("base64"),
969
+ spc: await this.ContentSpaceId()
970
+ };
971
+
972
+ if(libraryId) {
973
+ token.lib = libraryId;
974
+ }
975
+
976
+ const compressedToken = Pako.deflateRaw(Buffer.from(JSON.stringify(token), "utf-8"));
977
+ const signature = await this.authClient.Sign(Ethers.utils.keccak256(compressedToken));
978
+ const signatureBytes = Buffer.from(signature.replace(/^0x/, ""), "hex");
979
+
980
+ if(signatureBytes.length !== 65) {
981
+ throw Error("Unable to create plain token: Expected a 65-byte ES256K signature");
982
+ }
983
+
984
+ return `aplsjc${this.utils.B58(Buffer.concat([
985
+ signatureBytes,
986
+ Buffer.from(compressedToken)
987
+ ]))}`;
988
+ }
989
+
939
990
  async PersonalSign({
940
991
  message,
941
992
  addEthereumPrefix,
package/src/EthClient.js CHANGED
@@ -309,6 +309,7 @@ class EthClient {
309
309
  methodName,
310
310
  methodArgs,
311
311
  value,
312
+ overrides={},
312
313
  timeout,
313
314
  formatArguments=true,
314
315
  cacheContract=true,
@@ -319,7 +320,6 @@ class EthClient {
319
320
  if(!abi) { abi = await this.client.ContractAbi({contractAddress}); }
320
321
 
321
322
  const contract = this.Contract({contractAddress, abi, cacheContract, overrideCachedContract});
322
-
323
323
  // Make method call
324
324
  const createMethodCall = await this.CallContractMethod({
325
325
  contract,
@@ -327,6 +327,7 @@ class EthClient {
327
327
  methodName,
328
328
  methodArgs,
329
329
  value,
330
+ overrides,
330
331
  formatArguments,
331
332
  cacheContract
332
333
  });
@@ -375,6 +375,7 @@ class FrameClient {
375
375
  "CreateNTPInstance",
376
376
  "CreateNonOwnerCap",
377
377
  "CreatePart",
378
+ "CreatePlainToken",
378
379
  "CreateProductionMaster",
379
380
  "CreateShare",
380
381
  "CreateSignedMessageJSON",
@@ -9,6 +9,7 @@ const objectPath = require("object-path");
9
9
 
10
10
  const HttpClient = require("../HttpClient");
11
11
  const ContentObjectAudit = require("../ContentObjectAudit");
12
+ const bs58 = require("bs58");
12
13
 
13
14
  const {
14
15
  ValidateLibrary,
@@ -17,6 +18,7 @@ const {
17
18
  ValidatePartHash,
18
19
  ValidateWriteToken,
19
20
  ValidateParameters,
21
+ ValidatePresence,
20
22
  } = require("../Validation");
21
23
 
22
24
  const MergeWith = require("lodash/mergeWith");
@@ -2713,7 +2715,6 @@ exports.LinkData = async function({libraryId, objectId, versionHash, writeToken,
2713
2715
  );
2714
2716
  };
2715
2717
 
2716
-
2717
2718
  /* Encryption */
2718
2719
 
2719
2720
  exports.CreateEncryptionConk = async function({libraryId, objectId, versionHash, writeToken, createKMSConk=true}) {
@@ -2793,6 +2794,74 @@ exports.CreateEncryptionConk = async function({libraryId, objectId, versionHash,
2793
2794
  return this.encryptionConks[objectId];
2794
2795
  };
2795
2796
 
2797
+ /**
2798
+ * Encrypt the owner encryption key using the new user details provided
2799
+ *
2800
+ * @methodGroup Encryption
2801
+ * @namedParams
2802
+ * @param {string=} libraryId - ID of a library
2803
+ * @param {string=} objectId - ID of an object
2804
+ * @param {string=} versionHash - Hash of an object version
2805
+ * @param {string=} writeToken - The write token for the object
2806
+ * @param {Object=} newEncodedUserPublicKey - raw public key or base-58 encoded publicKey of the new user prefixed 'kupk'
2807
+ */
2808
+ exports.MigrateEncryptionConkForUserProvided = async function({libraryId, objectId, versionHash, writeToken, newEncodedUserPublicKey}) {
2809
+ if(this.signer.remoteSigner) {
2810
+ return;
2811
+ }
2812
+
2813
+ ValidateParameters({libraryId, objectId, versionHash});
2814
+ ValidateWriteToken(writeToken);
2815
+
2816
+ if(!objectId) {
2817
+ objectId = this.utils.DecodeVersionHash(versionHash).objectId;
2818
+ }
2819
+
2820
+ ValidatePresence("newEncodedUserPublicKey", newEncodedUserPublicKey);
2821
+
2822
+ let publicKey;
2823
+ if(!newEncodedUserPublicKey.startsWith("kupk")){
2824
+ publicKey = newEncodedUserPublicKey;
2825
+ } else {
2826
+ const publicKeyBytes = bs58.decode(newEncodedUserPublicKey.slice(4));
2827
+ if(publicKeyBytes.length !== 65) {
2828
+ publicKey = "0x" + Buffer.concat([Buffer.from([0x04]), publicKeyBytes]).toString("hex");
2829
+ } else {
2830
+ publicKey = "0x" + publicKeyBytes.toString("hex");
2831
+ }
2832
+ }
2833
+
2834
+ // Decrypt using existing user key
2835
+ const existingCapKey = `eluv.caps.iusr${this.utils.AddressToHash(this.signer.address)}`;
2836
+ const existingUserCap =
2837
+ await this.ContentObjectMetadata({
2838
+ libraryId,
2839
+ objectId,
2840
+ writeToken,
2841
+ metadataSubtree: existingCapKey
2842
+ });
2843
+
2844
+ if(!existingUserCap) {
2845
+ throw (`No encryption conk present for ${objectId} for user ${this.signer.address}`);
2846
+ }
2847
+
2848
+ this.encryptionConks[objectId] = await this.Crypto.DecryptCap(existingUserCap, this.signer._signingKey().privateKey);
2849
+
2850
+ // Encrypt with the new key
2851
+ const encryptedConk = await this.Crypto.EncryptConk(this.encryptionConks[objectId], publicKey);
2852
+ const newUserCap = `eluv.caps.iusr${this.utils.AddressToHash(this.utils.PublicKeyToAddress(publicKey))}`;
2853
+
2854
+ await this.ReplaceMetadata({
2855
+ libraryId,
2856
+ objectId,
2857
+ writeToken,
2858
+ metadataSubtree: newUserCap,
2859
+ metadata: encryptedConk
2860
+ });
2861
+
2862
+ return this.encryptionConks[objectId];
2863
+ };
2864
+
2796
2865
  /**
2797
2866
  * Retrieve the encryption conk for the specified object. If one has not yet been created
2798
2867
  * and a writeToken has been specified, this method will create a new conk and