@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.
@@ -1090,9 +1090,9 @@ exports.StreamStatus = async function({name, showParams=false, writeToken}) {
1090
1090
  status.recordingStatus = lroStatus.custom.status;
1091
1091
  }
1092
1092
  } catch(error) {
1093
- console.log("LRO Status (failed): ", error.response.statusCode);
1093
+ console.log("LRO Status (failed): ", error.response?.statusCode);
1094
1094
  status.state = "stopped";
1095
- status.error = error.response;
1095
+ status.error = error.response || error.message;
1096
1096
  return status;
1097
1097
  }
1098
1098
 
@@ -3532,6 +3532,13 @@ exports.OutputsList = async function({libraryId, objectId, includeState=true}) {
3532
3532
  method: "live/outputs",
3533
3533
  constant: true
3534
3534
  });
3535
+ } catch(error) {
3536
+ if(error.status === 404) {
3537
+ // Stream object may have been deleted
3538
+ return {};
3539
+ }
3540
+
3541
+ throw error;
3535
3542
  } finally {
3536
3543
  restore();
3537
3544
  }
@@ -3544,17 +3551,22 @@ exports.OutputsList = async function({libraryId, objectId, includeState=true}) {
3544
3551
  const streamId = value.input?.stream;
3545
3552
  if(!streamId) { return; }
3546
3553
 
3547
- const [streamLibraryId, streamStatus] = await Promise.all([
3548
- this.ContentObjectLibraryId({objectId: streamId}),
3549
- this.StreamStatus({name: streamId})
3550
- ]);
3551
-
3552
- value.input.name = await this.ContentObjectMetadata({
3553
- libraryId: streamLibraryId,
3554
- objectId: streamId,
3555
- metadataSubtree: "/public/name",
3556
- });
3557
- value.input.status = streamStatus?.state;
3554
+ try {
3555
+ const [streamLibraryId, streamStatus] = await Promise.all([
3556
+ this.ContentObjectLibraryId({objectId: streamId}),
3557
+ this.StreamStatus({name: streamId})
3558
+ ]);
3559
+
3560
+ value.input.name = await this.ContentObjectMetadata({
3561
+ libraryId: streamLibraryId,
3562
+ objectId: streamId,
3563
+ metadataSubtree: "/public/name",
3564
+ });
3565
+ value.input.status = streamStatus?.state;
3566
+ } catch(error) {
3567
+ // Stream object may have been deleted
3568
+ value.input.status = "unavailable";
3569
+ }
3558
3570
  }
3559
3571
  );
3560
3572
 
@@ -3569,9 +3581,13 @@ exports.OutputsList = async function({libraryId, objectId, includeState=true}) {
3569
3581
 
3570
3582
  const nodeUrls = {};
3571
3583
  await this.utils.LimitedMap(10, nodeIds, async nodeId => {
3572
- const nodes = await this.SpaceNodes({matchNodeId: nodeId});
3573
- const fabricUrl = nodes?.[0]?.services?.fabric_api?.urls?.[0];
3574
- if(fabricUrl) { nodeUrls[nodeId] = fabricUrl; }
3584
+ try {
3585
+ const nodes = await this.SpaceNodes({matchNodeId: nodeId});
3586
+ const fabricUrl = nodes?.[0]?.services?.fabric_api?.urls?.[0];
3587
+ if(fabricUrl) { nodeUrls[nodeId] = fabricUrl; }
3588
+ } catch(error) {
3589
+ this.Log(`Failed to resolve node ${nodeId}: ${error.message}`, true);
3590
+ }
3575
3591
  });
3576
3592
 
3577
3593
  // Rewrite fabric-generated srt_pull URLs to the egress host, and group outputs by node
@@ -0,0 +1,62 @@
1
+ const {NewOpt} = require("./lib/options");
2
+ const Utility = require("./lib/Utility");
3
+
4
+ const Client = require("./lib/concerns/Client");
5
+ const Edit = require("./lib/concerns/Edit");
6
+
7
+ class MigrateEncryptionConkForNewUser extends Utility {
8
+ blueprint() {
9
+ return {
10
+ concerns: [Client, Edit],
11
+ options: [
12
+ NewOpt("objectId",
13
+ {
14
+ descTemplate: "object Id",
15
+ type: "string",
16
+ demand: true
17
+ }),
18
+ NewOpt("publicKey",
19
+ {
20
+ descTemplate: "new user public key with/without encoded form",
21
+ type: "string",
22
+ demand: true
23
+ })
24
+ ]
25
+ };
26
+ }
27
+
28
+ async body() {
29
+ const logger = this.logger;
30
+ const {objectId, publicKey} = this.args;
31
+
32
+ const client = await this.concerns.Client.get();
33
+ const libraryId = await client.ContentObjectLibraryId({objectId});
34
+
35
+ const res = await client.EditContentObject({libraryId, objectId});
36
+
37
+ await client.MigrateEncryptionConkForUserProvided({
38
+ libraryId,
39
+ objectId,
40
+ writeToken: res.writeToken,
41
+ newEncodedUserPublicKey: publicKey
42
+ });
43
+ logger.log("Migration of encryption conk is complete...");
44
+
45
+ const versionHash = await this.concerns.Edit.finalize({
46
+ libraryId,
47
+ objectId,
48
+ writeToken:res.writeToken
49
+ });
50
+ logger.log("version hash", versionHash);
51
+ }
52
+
53
+ header() {
54
+ return `Add encryption conk for user provided '${this.args.objectId}':`;
55
+ }
56
+ }
57
+
58
+ if(require.main === module) {
59
+ Utility.cmdLineInvoke(MigrateEncryptionConkForNewUser);
60
+ } else {
61
+ module.exports = MigrateEncryptionConkForNewUser;
62
+ }
@@ -1,6 +1,6 @@
1
1
  // Create new production master from specified file(s)
2
2
 
3
- const {ModOpt, StdOpt} = require("./lib/options");
3
+ const {ModOpt, StdOpt, NewOpt} = require("./lib/options");
4
4
  const Utility = require("./lib/Utility");
5
5
 
6
6
  const ArgNoWait = require("./lib/concerns/ArgNoWait");
@@ -16,14 +16,19 @@ class ObjectAddFiles extends Utility {
16
16
  concerns: [Logger, ExistObj, Edit, ArgNoWait, LocalFile, CloudFile],
17
17
  options: [
18
18
  ModOpt("files", {X: "to add"}),
19
- StdOpt("encrypt", {X: "uploaded files"})
19
+ StdOpt("encrypt", {X: "uploaded files"}),
20
+ NewOpt("resume", {
21
+ descTemplate: "If specified, resume jobs for the given write token (--resume 'write_token')",
22
+ group: "Main",
23
+ type: "string"
24
+ })
20
25
  ]
21
26
  };
22
27
  }
23
28
 
24
29
  async body() {
25
30
  const logger = this.logger;
26
- const {encrypt, noWait} = this.args;
31
+ const {encrypt, noWait, resume: resumeArg} = this.args;
27
32
 
28
33
  let access;
29
34
  if(this.args.s3Reference || this.args.s3Copy) access = this.concerns.CloudFile.credentialSet();
@@ -35,10 +40,22 @@ class ObjectAddFiles extends Utility {
35
40
 
36
41
  const {libraryId, objectId} = await this.concerns.ExistObj.argsProc();
37
42
 
38
- const writeToken = await this.concerns.Edit.getWriteToken({
39
- libraryId,
40
- objectId
41
- });
43
+ let writeToken;
44
+ let resume=false;
45
+ if(resumeArg) {
46
+ writeToken = resumeArg;
47
+ resume=true;
48
+ } else {
49
+ // create new write token
50
+ writeToken = await this.concerns.Edit.getWriteToken({
51
+ libraryId,
52
+ objectId
53
+ });
54
+ }
55
+ logger.data("WRITE_TOKEN", writeToken);
56
+ // eslint-disable-next-line no-console
57
+ console.log("Using write token:", writeToken);
58
+
42
59
 
43
60
  if(access) {
44
61
  await this.concerns.CloudFile.add({
@@ -47,7 +64,8 @@ class ObjectAddFiles extends Utility {
47
64
  writeToken,
48
65
  access,
49
66
  fileInfo,
50
- encrypt
67
+ encrypt,
68
+ resume,
51
69
  });
52
70
  } else {
53
71
  await this.concerns.LocalFile.add({
@@ -55,12 +73,14 @@ class ObjectAddFiles extends Utility {
55
73
  objectId,
56
74
  writeToken,
57
75
  fileInfo,
58
- encrypt
76
+ encrypt,
77
+ resume,
59
78
  });
60
79
  // Close file handles
61
80
  this.concerns.LocalFile.closeFileHandles(fileHandles);
62
81
  }
63
82
 
83
+ // finalize the write token
64
84
  const hash = await this.concerns.Edit.finalize({
65
85
  libraryId,
66
86
  noWait,
@@ -95,7 +95,7 @@ const New = context => {
95
95
  );
96
96
  };
97
97
 
98
- const add = async ({libraryId, objectId, writeToken, files, access, encrypt, copy}) => {
98
+ const add = async ({libraryId, objectId, writeToken, files, access, encrypt, copy, resume}) => {
99
99
  if(kindOf(copy) === "undefined") copy = isCopy();
100
100
  files = files || context.args.files;
101
101
  const groupedFiles = groupByPathMatch(access, files);
@@ -125,6 +125,7 @@ const New = context => {
125
125
  secret,
126
126
  signedUrl,
127
127
  copy,
128
+ resume,
128
129
  callback,
129
130
  encryption: encrypt ? "cgck" : "none"
130
131
  });
@@ -19,7 +19,7 @@ const blueprint = {
19
19
 
20
20
  const New = context => {
21
21
 
22
- const add = async ({libraryId, objectId, writeToken, fileInfo, encrypt}) => {
22
+ const add = async ({libraryId, objectId, writeToken, fileInfo, encrypt, resume}) => {
23
23
  const client = await context.concerns.Client.get();
24
24
  await client.UploadFiles({
25
25
  libraryId,
@@ -27,6 +27,7 @@ const New = context => {
27
27
  writeToken,
28
28
  fileInfo,
29
29
  callback,
30
+ resume,
30
31
  encryption: encrypt ? "cgck" : "none"
31
32
  });
32
33
  };
@@ -1,281 +0,0 @@
1
- var _regeneratorRuntime = require("@babel/runtime/regenerator");
2
- var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
3
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
4
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
5
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
6
- var CBOR = require("cbor");
7
- var SJCL = require("sjcl");
8
- var MultiHash = require("multihashes");
9
- var DeepEqual = require("deep-equal");
10
- var Utils = require("./Utils");
11
- var ContentObjectVerification = {
12
- VerifyContentObject: function VerifyContentObject(_ref) {
13
- return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
14
- var client, libraryId, objectId, versionHash, response, partHash, qpartsResponse, partVerification, qmdHash, metadataPartHash, metadataPartResponse, metadataVerification, metadata, qstructHash, structPartHash, structPartResponse, structVerification;
15
- return _regeneratorRuntime.wrap(function _callee$(_context) {
16
- while (1) switch (_context.prev = _context.next) {
17
- case 0:
18
- client = _ref.client, libraryId = _ref.libraryId, objectId = _ref.objectId, versionHash = _ref.versionHash;
19
- response = {
20
- hash: versionHash
21
- };
22
- partHash = Utils.DecodeVersionHash(versionHash).partHash;
23
- _context.next = 5;
24
- return client.QParts({
25
- libraryId: libraryId,
26
- objectId: objectId,
27
- partHash: partHash,
28
- format: "arrayBuffer"
29
- }).then(function (response) {
30
- return Buffer.from(response);
31
- });
32
- case 5:
33
- qpartsResponse = _context.sent;
34
- partVerification = ContentObjectVerification._VerifyPart({
35
- partHash: partHash,
36
- qpartsResponse: qpartsResponse
37
- });
38
- if (partVerification.valid) {
39
- response.qref = {
40
- valid: true
41
- };
42
- } else {
43
- response.qref = {
44
- valid: false,
45
- error: partVerification.error.message
46
- };
47
- }
48
- response.qref.hash = partHash;
49
- if (!response.qref.valid) {
50
- _context.next = 32;
51
- break;
52
- }
53
- // Validate Metadata
54
- qmdHash = partVerification.cbor.QmdHash.value;
55
- metadataPartHash = "hqp_" + MultiHash.toB58String(qmdHash.slice(1, qmdHash.length));
56
- _context.next = 14;
57
- return client.QParts({
58
- libraryId: libraryId,
59
- objectId: objectId,
60
- partHash: metadataPartHash,
61
- format: "arrayBuffer"
62
- }).then(function (response) {
63
- return Buffer.from(response);
64
- });
65
- case 14:
66
- metadataPartResponse = _context.sent;
67
- metadataVerification = ContentObjectVerification._VerifyPart({
68
- partHash: metadataPartHash,
69
- qpartsResponse: metadataPartResponse
70
- });
71
- if (metadataVerification.valid) {
72
- response.qmd = {
73
- valid: true
74
- };
75
- } else {
76
- response.qmd = {
77
- valid: false,
78
- error: metadataVerification.error.message
79
- };
80
- }
81
- response.qmd.hash = metadataPartHash;
82
- if (!(response.qmd.valid && libraryId)) {
83
- _context.next = 23;
84
- break;
85
- }
86
- _context.next = 21;
87
- return client.ContentObjectMetadata({
88
- libraryId: libraryId,
89
- objectId: objectId,
90
- versionHash: partHash.replace("hqp_", "hq__")
91
- });
92
- case 21:
93
- metadata = _context.sent;
94
- response.qmd.check = ContentObjectVerification._VerifyMetadata({
95
- metadataCbor: metadataVerification.cbor,
96
- metadata: metadata
97
- });
98
- case 23:
99
- // Validate Qstruct
100
- qstructHash = partVerification.cbor.QstructHash.value;
101
- structPartHash = "hqp_" + MultiHash.toB58String(qstructHash.slice(1, qstructHash.length));
102
- _context.next = 27;
103
- return client.QParts({
104
- libraryId: libraryId,
105
- objectId: objectId,
106
- partHash: structPartHash,
107
- format: "arrayBuffer"
108
- }).then(function (response) {
109
- return Buffer.from(response);
110
- });
111
- case 27:
112
- structPartResponse = _context.sent;
113
- structVerification = ContentObjectVerification._VerifyPart({
114
- partHash: structPartHash,
115
- qpartsResponse: structPartResponse
116
- });
117
- if (structVerification.valid) {
118
- response.qstruct = {
119
- valid: true
120
- };
121
- } else {
122
- response.qstruct = {
123
- valid: false,
124
- error: structVerification.error.message
125
- };
126
- }
127
- response.qstruct.hash = structPartHash;
128
- if (response.qstruct.valid) {
129
- response.qstruct.parts = ContentObjectVerification._FormatQStruct(structVerification.cbor.Parts);
130
- }
131
- case 32:
132
- response.valid = response.qref.valid && response.qmd.valid && response.qstruct.valid && (!response.qmd.check || response.qmd.check.valid);
133
- return _context.abrupt("return", response);
134
- case 34:
135
- case "end":
136
- return _context.stop();
137
- }
138
- }, _callee);
139
- }))();
140
- },
141
- // Content verification methods //
142
- _FormatQStruct: function _FormatQStruct(structParts) {
143
- if (!structParts) {
144
- return [];
145
- }
146
- return structParts.map(function (structPart) {
147
- return {
148
- hash: "hqp_" + MultiHash.toB58String(structPart.Hash.value.slice(1, structPart.Hash.length)),
149
- size: structPart.Size
150
- };
151
- });
152
- },
153
- _Hash: function _Hash(thing) {
154
- function fromBits(arr) {
155
- var out = [],
156
- bl = SJCL.bitArray.bitLength(arr),
157
- i,
158
- tmp;
159
- for (i = 0; i < bl / 8; i++) {
160
- if ((i & 3) === 0) {
161
- tmp = arr[i / 4];
162
- }
163
- out.push(tmp >>> 24);
164
- tmp <<= 8;
165
- }
166
- return out;
167
- }
168
- function toBits(bytes) {
169
- var out = [],
170
- i,
171
- tmp = 0;
172
- for (i = 0; i < bytes.length; i++) {
173
- tmp = tmp << 8 | bytes[i];
174
- if ((i & 3) === 3) {
175
- out.push(tmp);
176
- tmp = 0;
177
- }
178
- }
179
- if (i & 3) {
180
- out.push(SJCL.bitArray.partial(8 * (i & 3), tmp));
181
- }
182
- return out;
183
- }
184
- var digest = SJCL.hash.sha256.hash(toBits(thing));
185
- var bytes = fromBits(digest);
186
- var out = Buffer.from(bytes, "binary");
187
- return MultiHash.toB58String(MultiHash.encode(out, "sha2-256"));
188
- },
189
- _ParseCBOR: function _ParseCBOR(cborResponse) {
190
- var buffer = cborResponse.slice(7, cborResponse.length);
191
- var hex = buffer.toString("hex");
192
- return CBOR.decodeFirstSync(hex);
193
- },
194
- _VerifyPart: function _VerifyPart(_ref2) {
195
- var partHash = _ref2.partHash,
196
- qpartsResponse = _ref2.qpartsResponse;
197
- try {
198
- if (ContentObjectVerification._Hash(qpartsResponse) !== partHash.replace("hqp_", "")) {
199
- throw Error("Hashes do not match");
200
- }
201
- var cbor = ContentObjectVerification._ParseCBOR(qpartsResponse);
202
- return {
203
- valid: true,
204
- cbor: cbor
205
- };
206
- } catch (error) {
207
- return {
208
- valid: false,
209
- error: error
210
- };
211
- }
212
- },
213
- _VerifyMetadata: function _VerifyMetadata(_ref3) {
214
- var metadataCbor = _ref3.metadataCbor,
215
- metadata = _ref3.metadata;
216
- if (!metadataCbor) {
217
- metadataCbor = {};
218
- }
219
- if (!metadata) {
220
- metadata = {};
221
- }
222
- var response = {
223
- valid: true,
224
- invalidValues: []
225
- };
226
- var cborKeys = Object.keys(metadataCbor);
227
- var metadataKeys = Object.keys(metadata);
228
-
229
- // Find any difference between top level keys
230
- var differentKeys = cborKeys.filter(function (x) {
231
- return !metadataKeys.includes(x);
232
- }).concat(metadataKeys.filter(function (x) {
233
- return !cborKeys.includes(x);
234
- }));
235
- var _iterator = _createForOfIteratorHelper(differentKeys),
236
- _step;
237
- try {
238
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
239
- var key = _step.value;
240
- var cborValue = metadataCbor[key];
241
- var metadataValue = metadata[key];
242
- response.invalidValues.push({
243
- key: key,
244
- cborValue: cborValue,
245
- metadataValue: metadataValue
246
- });
247
- }
248
-
249
- // Deep comparison of up to 5 keys
250
- } catch (err) {
251
- _iterator.e(err);
252
- } finally {
253
- _iterator.f();
254
- }
255
- var _iterator2 = _createForOfIteratorHelper(Object.keys(metadataCbor).slice(0, 5)),
256
- _step2;
257
- try {
258
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
259
- var fieldToValidate = _step2.value;
260
- var _cborValue = metadataCbor[fieldToValidate];
261
- var _metadataValue = metadata[fieldToValidate];
262
- if (!DeepEqual(_cborValue, _metadataValue)) {
263
- response.invalidValues.push({
264
- key: fieldToValidate,
265
- cborValue: _cborValue,
266
- metadataValue: _metadataValue
267
- });
268
- }
269
- }
270
- } catch (err) {
271
- _iterator2.e(err);
272
- } finally {
273
- _iterator2.f();
274
- }
275
- if (response.invalidValues.length !== 0) {
276
- response.valid = false;
277
- }
278
- return response;
279
- }
280
- };
281
- module.exports = ContentObjectVerification;