@eluvio/elv-client-js 4.0.128 → 4.0.130
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
package/src/ElvClient.js
CHANGED
|
@@ -953,6 +953,8 @@ class ElvClient {
|
|
|
953
953
|
* @param {boolean} allowDecryption=false - If specified, the re-encryption key will be included in the token,
|
|
954
954
|
* enabling the user of this token to download encrypted content from the specified object
|
|
955
955
|
* @param {Object=} context - Additional JSON context
|
|
956
|
+
* @param {number=} issueTime - Issue Time in milliseconds
|
|
957
|
+
* @param {number=} expirationTime - Expiration Time in milliseconds
|
|
956
958
|
*/
|
|
957
959
|
async CreateSignedToken({
|
|
958
960
|
libraryId,
|
|
@@ -963,7 +965,9 @@ class ElvClient {
|
|
|
963
965
|
grantType="read",
|
|
964
966
|
allowDecryption=false,
|
|
965
967
|
duration,
|
|
966
|
-
context={}
|
|
968
|
+
context={},
|
|
969
|
+
issueTime,
|
|
970
|
+
expirationTime
|
|
967
971
|
}) {
|
|
968
972
|
if(!subject) {
|
|
969
973
|
subject = `iusr${this.utils.AddressToHash(await this.CurrentAccountAddress())}`;
|
|
@@ -973,12 +977,14 @@ class ElvClient {
|
|
|
973
977
|
context["elv:delegation-id"] = policyId;
|
|
974
978
|
}
|
|
975
979
|
|
|
980
|
+
const issueDateTime = issueTime || Date.now();
|
|
981
|
+
|
|
976
982
|
let token = {
|
|
977
983
|
adr: Buffer.from(await this.CurrentAccountAddress().replace(/^0x/, ""), "hex").toString("base64"),
|
|
978
984
|
sub: subject,
|
|
979
985
|
spc: await this.ContentSpaceId(),
|
|
980
|
-
iat:
|
|
981
|
-
exp:
|
|
986
|
+
iat: issueDateTime,
|
|
987
|
+
exp: expirationTime || (issueDateTime + duration),
|
|
982
988
|
gra: grantType,
|
|
983
989
|
ctx: context
|
|
984
990
|
};
|
package/src/HttpClient.js
CHANGED
|
@@ -114,10 +114,10 @@ class HttpClient {
|
|
|
114
114
|
} catch(error) {
|
|
115
115
|
response = {
|
|
116
116
|
ok: false,
|
|
117
|
-
status: 500,
|
|
117
|
+
status: (error && error.status) || 500,
|
|
118
118
|
statusText: "ElvClient Error: " + error.message,
|
|
119
119
|
url: uri.toString(),
|
|
120
|
-
|
|
120
|
+
error
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -167,7 +167,8 @@ class HttpClient {
|
|
|
167
167
|
message: response.statusText,
|
|
168
168
|
url: uri.toString(),
|
|
169
169
|
body: errorBody,
|
|
170
|
-
requestParams: fetchParameters
|
|
170
|
+
requestParams: fetchParameters,
|
|
171
|
+
response
|
|
171
172
|
};
|
|
172
173
|
|
|
173
174
|
if(this.debug) this.Log(
|
|
@@ -934,8 +934,8 @@ exports.ContentObjectMetadata = async function({
|
|
|
934
934
|
// For a 404 error, check if error was due to write token not found
|
|
935
935
|
const errQwtoken = objectPath.get(error.body, "errors.0.cause.cause.cause.qwtoken");
|
|
936
936
|
if(errQwtoken) {
|
|
937
|
-
// if so,
|
|
938
|
-
throw
|
|
937
|
+
// if so, throw more specific/informative error rather than the generic 'Not found' error
|
|
938
|
+
throw new Error(`Write token ${errQwtoken} not found`);
|
|
939
939
|
} else {
|
|
940
940
|
// For all other 404 errors (not just 'subtree not found'), suppress error and
|
|
941
941
|
// return an empty value. (there are function call chains that depend on this behavior,
|
|
@@ -251,11 +251,11 @@ exports.CreateContentType = async function({name, metadata={}, bitcode}) {
|
|
|
251
251
|
* @param {string} name - Library name
|
|
252
252
|
* @param {string=} description - Library description
|
|
253
253
|
* @param {blob=} image - Image associated with the library
|
|
254
|
-
* @param {string=}
|
|
254
|
+
* @param {string=} imageName - Name of the image associated with the library (required if image specified)
|
|
255
255
|
* @param {Object=} metadata - Metadata of library object
|
|
256
256
|
* @param {string=} kmsId - ID of the KMS to use for content in this library. If not specified,
|
|
257
257
|
* the default KMS will be used.
|
|
258
|
-
* @param {string=}
|
|
258
|
+
* @param {string=} tenantContractId - ID of the tenant to use for this library
|
|
259
259
|
*
|
|
260
260
|
* @returns {Promise<string>} - Library ID of created library
|
|
261
261
|
*/
|
|
@@ -420,26 +420,25 @@ exports.SetContentObjectImage = async function({libraryId, objectId, writeToken,
|
|
|
420
420
|
* @param {string} libraryId - ID of the library to delete
|
|
421
421
|
*/
|
|
422
422
|
exports.DeleteContentLibrary = async function({libraryId}) {
|
|
423
|
-
throw Error(
|
|
424
|
-
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
});
|
|
423
|
+
throw Error(`Delete library not supported. (${libraryId})`);
|
|
424
|
+
|
|
425
|
+
// ValidateLibrary(libraryId);
|
|
426
|
+
//
|
|
427
|
+
// let path = UrlJoin("qlibs", libraryId);
|
|
428
|
+
//
|
|
429
|
+
// const authorizationHeader = await this.authClient.AuthorizationHeader({libraryId, update: true});
|
|
430
|
+
//
|
|
431
|
+
// await this.CallContractMethodAndWait({
|
|
432
|
+
// contractAddress: this.utils.HashToAddress(libraryId),
|
|
433
|
+
// methodName: "kill",
|
|
434
|
+
// methodArgs: []
|
|
435
|
+
// });
|
|
436
|
+
//
|
|
437
|
+
// await this.HttpClient.Request({
|
|
438
|
+
// headers: authorizationHeader,
|
|
439
|
+
// method: "DELETE",
|
|
440
|
+
// path: path
|
|
441
|
+
// });
|
|
443
442
|
};
|
|
444
443
|
|
|
445
444
|
/* Library Content Type Management */
|
|
@@ -542,7 +541,11 @@ exports.RemoveLibraryContentType = async function({libraryId, typeId, typeName,
|
|
|
542
541
|
*
|
|
543
542
|
* meta: Metadata to use for the new object
|
|
544
543
|
*
|
|
545
|
-
*
|
|
544
|
+
* noEncryptionConk: Set to true to prevent creation of an encryption conk for the object
|
|
545
|
+
*
|
|
546
|
+
* createKMSConk: Set to true to create a KMS conk for object (usually for sharing a playable object) (incompatible with noEncryptionConk: true)
|
|
547
|
+
*
|
|
548
|
+
* @returns {Promise<Object>} - Response containing the object ID and write token of the draft, as well as the url of the node that created the write token.
|
|
546
549
|
*/
|
|
547
550
|
exports.CreateContentObject = async function({libraryId, objectId, options={}}) {
|
|
548
551
|
ValidateLibrary(libraryId);
|
|
@@ -550,6 +553,8 @@ exports.CreateContentObject = async function({libraryId, objectId, options={}})
|
|
|
550
553
|
|
|
551
554
|
this.Log(`Creating content object: ${libraryId} ${objectId || ""}`);
|
|
552
555
|
|
|
556
|
+
if(options.noEncryptionConk && options.createKMSConk) throw new Error("Incompatible options: noEncryptionConk and createKMSConk both set to true");
|
|
557
|
+
|
|
553
558
|
// Look up content type, if specified
|
|
554
559
|
let typeId;
|
|
555
560
|
if(options.type) {
|
|
@@ -605,10 +610,15 @@ exports.CreateContentObject = async function({libraryId, objectId, options={}})
|
|
|
605
610
|
headers: await this.authClient.AuthorizationHeader({libraryId, objectId, update: true}),
|
|
606
611
|
method: "POST",
|
|
607
612
|
path: path,
|
|
608
|
-
body: options
|
|
613
|
+
body: { // filter out options not recognized by server (noEncryptionConk, createKMSConk)
|
|
614
|
+
type: options.type,
|
|
615
|
+
meta: options.meta
|
|
616
|
+
}
|
|
609
617
|
});
|
|
618
|
+
|
|
610
619
|
// extract the url for the node that handled the request
|
|
611
|
-
//
|
|
620
|
+
// (not strictly needed now that we can quickly look up node URL for a write token,
|
|
621
|
+
// but still convenient)
|
|
612
622
|
const nodeUrl = (new URL(rawCreateResponse.url)).origin;
|
|
613
623
|
const createResponse = await this.utils.ResponseToJson(
|
|
614
624
|
rawCreateResponse,
|
|
@@ -616,6 +626,16 @@ exports.CreateContentObject = async function({libraryId, objectId, options={}})
|
|
|
616
626
|
this.HttpClient.Log.bind(this.HttpClient)
|
|
617
627
|
);
|
|
618
628
|
|
|
629
|
+
// create EncryptionConk and possibly KMSConk depending on options
|
|
630
|
+
if(!options.noEncryptionConk) await this.CreateEncryptionConk(
|
|
631
|
+
{
|
|
632
|
+
libraryId,
|
|
633
|
+
objectId,
|
|
634
|
+
writeToken: createResponse.write_token,
|
|
635
|
+
createKMSConk: options.createKMSConk
|
|
636
|
+
}
|
|
637
|
+
);
|
|
638
|
+
|
|
619
639
|
// Record the node used in creating this write token
|
|
620
640
|
this.RecordWriteToken({writeToken: createResponse.write_token, fabricNodeUrl: nodeUrl});
|
|
621
641
|
|
|
@@ -1449,14 +1469,14 @@ exports.CreateLinks = async function({
|
|
|
1449
1469
|
10,
|
|
1450
1470
|
links,
|
|
1451
1471
|
async info => {
|
|
1452
|
-
const path = info.path.replace(/^(
|
|
1472
|
+
const path = info.path.replace(/^([/.])+/, "");
|
|
1453
1473
|
|
|
1454
1474
|
let type = (info.type || "file") === "file" ? "files" : info.type;
|
|
1455
1475
|
if(type === "metadata") { type = "meta"; }
|
|
1456
1476
|
|
|
1457
1477
|
let target;
|
|
1458
1478
|
let authTarget;
|
|
1459
|
-
target = authTarget = info.target.replace(/^(
|
|
1479
|
+
target = authTarget = info.target.replace(/^([/.])+/, "");
|
|
1460
1480
|
if(info.targetHash) {
|
|
1461
1481
|
target = `/qfab/${info.targetHash}/${type}/${target}`;
|
|
1462
1482
|
} else {
|
package/src/client/LiveConf.js
CHANGED
|
@@ -443,6 +443,10 @@ class LiveConf {
|
|
|
443
443
|
conf.live_recording.recording_config.recording_params.part_ttl = customSettings.part_ttl;
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
+
if(Object.hasOwn(customSettings, "persistent")) {
|
|
447
|
+
conf.live_recording.recording_config.recording_params.persistent = customSettings.persistent;
|
|
448
|
+
}
|
|
449
|
+
|
|
446
450
|
if(customSettings.connection_timeout) {
|
|
447
451
|
conf.live_recording.recording_config.recording_params.xc_params.connection_timeout = customSettings.connection_timeout;
|
|
448
452
|
}
|
|
@@ -451,6 +455,10 @@ class LiveConf {
|
|
|
451
455
|
conf.live_recording.recording_config.recording_params.reconnect_timeout = customSettings.reconnect_timeout;
|
|
452
456
|
}
|
|
453
457
|
|
|
458
|
+
if(Object.hasOwn(customSettings, "copy_mpegts")) {
|
|
459
|
+
conf.live_recording.recording_config.recording_params.xc_params.copy_mpegts = customSettings.copy_mpegts;
|
|
460
|
+
}
|
|
461
|
+
|
|
454
462
|
// Fill in specifics for protocol
|
|
455
463
|
switch(this.probeKind()) {
|
|
456
464
|
case "udp":
|