@eluvio/elv-client-js 4.2.25 → 4.2.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eluvio/elv-client-js",
3
- "version": "4.2.25",
3
+ "version": "4.2.29",
4
4
  "description": "Javascript client for the Eluvio Content Fabric",
5
5
  "main": "src/index.js",
6
6
  "author": "Kevin Talmadge",
@@ -35,6 +35,10 @@
35
35
  "browser": {
36
36
  "fs": false
37
37
  },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/eluv-io/elv-client-js.git"
41
+ },
38
42
  "files": [
39
43
  "/build",
40
44
  "/dist",
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
  });
@@ -78,6 +78,11 @@ const MezJobMainOfferingKey = function(abrMezOfferings) {
78
78
  * - ...
79
79
  * - ]
80
80
  * -
81
+ * - For a presigned URL, `path` and `storage_endpoint` are not required and `cloud_credentials` should be:
82
+ * - {
83
+ * - signed_url: "YOUR_PRESIGNED_S3_URL"
84
+ * - }
85
+ * -
81
86
  * - The simplest case is a one element array with .path_matchers == [".*"], in which case the same credentials will be used for all items in fileInfo
82
87
  *
83
88
  * @throws {Object} error - If the initialization of the master fails, error details can be found in error.body
@@ -127,8 +132,11 @@ exports.CreateProductionMaster = async function({
127
132
  let matched = false;
128
133
  for(let j = 0; !matched && j < access.length; j++) {
129
134
  let credentialSet = access[j];
135
+ const remoteAccess = credentialSet.remote_access;
130
136
  // strip trailing slash to get bucket name for credential set
131
- const credentialSetBucket = credentialSet.remote_access.path.replace(/\/$/, "");
137
+ const credentialSetBucket = remoteAccess.path
138
+ ? remoteAccess.path.replace(/\/$/, "")
139
+ : undefined;
132
140
  const matchers = credentialSet.path_matchers;
133
141
  for(let k = 0; !matched && k < matchers.length; k++) {
134
142
  const matcher = new RegExp(matchers[k]);
@@ -139,7 +147,7 @@ exports.CreateProductionMaster = async function({
139
147
  const s3prefixMatch = (s3prefixRegex.exec(fileSourcePath));
140
148
  if(s3prefixMatch) {
141
149
  const bucketName = s3prefixMatch[1];
142
- if(bucketName !== credentialSetBucket) {
150
+ if(credentialSetBucket && bucketName !== credentialSetBucket) {
143
151
  throw Error("Full S3 file path \"" + fileSourcePath + "\" matched to credential set with different bucket name '" + credentialSetBucket + "'");
144
152
  }
145
153
  }
@@ -154,7 +162,7 @@ exports.CreateProductionMaster = async function({
154
162
  }
155
163
  }
156
164
  if(!matched) {
157
- throw Error("no credential set found for file path: \"" + filePath + "\"");
165
+ throw Error("no credential set found for file path: \"" + oneFileInfo.source + "\"");
158
166
  }
159
167
  }
160
168
 
@@ -162,10 +170,13 @@ exports.CreateProductionMaster = async function({
162
170
  for(let i = 0; i < access.length; i++) {
163
171
  const credentialSet = access[i];
164
172
  if(credentialSet.hasOwnProperty("matched") && credentialSet.matched.length > 0) {
165
- const region = credentialSet.remote_access.storage_endpoint.region;
166
- const bucket = credentialSet.remote_access.path.replace(/\/$/, "");
167
- const accessKey = credentialSet.remote_access.cloud_credentials.access_key_id;
168
- const secret = credentialSet.remote_access.cloud_credentials.secret_access_key;
173
+ const remoteAccess = credentialSet.remote_access;
174
+ const cloudCredentials = remoteAccess.cloud_credentials;
175
+ const region = remoteAccess.storage_endpoint && remoteAccess.storage_endpoint.region;
176
+ const bucket = remoteAccess.path && remoteAccess.path.replace(/\/$/, "");
177
+ const accessKey = cloudCredentials.access_key_id;
178
+ const secret = cloudCredentials.secret_access_key;
179
+ const signedUrl = cloudCredentials.signed_url;
169
180
 
170
181
  await this.UploadFilesFromS3({
171
182
  libraryId,
@@ -176,6 +187,7 @@ exports.CreateProductionMaster = async function({
176
187
  bucket,
177
188
  accessKey,
178
189
  secret,
190
+ signedUrl,
179
191
  copy,
180
192
  callback,
181
193
  encryption: encrypt ? "cgck" : "none"
@@ -212,22 +224,24 @@ exports.CreateProductionMaster = async function({
212
224
  constant: false
213
225
  });
214
226
 
227
+ const mergeMetadata = {
228
+ ...(metadata || {}),
229
+ name: name !== undefined ? name : (metadata || {}).name,
230
+ description: description !== undefined ? description : (metadata || {}).description,
231
+ reference: access && !copy,
232
+ public: {
233
+ ...((metadata || {}).public || {}),
234
+ name: name !== undefined ? name : ((metadata || {}).public || {}).name,
235
+ description: description !== undefined ? description : ((metadata || {}).public || {}).description
236
+ },
237
+ elv_created_at: new Date().getTime(),
238
+ };
239
+
215
240
  await this.MergeMetadata({
216
241
  libraryId,
217
242
  objectId,
218
243
  writeToken,
219
- metadata: {
220
- ...(metadata || {}),
221
- name,
222
- description,
223
- reference: access && !copy,
224
- public: {
225
- ...((metadata || {}).public || {}),
226
- name: name || "",
227
- description: description || ""
228
- },
229
- elv_created_at: new Date().getTime(),
230
- }
244
+ metadata: mergeMetadata
231
245
  });
232
246
 
233
247
  let additionalReturnVals;
@@ -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