@eluvio/elv-client-js 3.2.40 → 3.2.42
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/dist/ElvClient-min.js +4 -4
- package/dist/ElvClient-node-min.js +6 -6
- package/dist/ElvWalletClient-min.js +4 -4
- package/dist/ElvWalletClient-node-min.js +9 -9
- package/dist/src/AuthorizationClient.js +507 -599
- package/dist/src/client/ContentManagement.js +153 -54
- package/dist/src/walletClient/Notifications.js +196 -0
- package/dist/src/walletClient/index.js +1 -0
- package/package.json +1 -1
- package/src/AuthorizationClient.js +0 -43
- package/src/client/ContentAccess.js +0 -1
- package/src/client/ContentManagement.js +72 -10
- package/src/walletClient/Notifications.js +109 -0
- package/src/walletClient/index.js +1 -0
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
const UrlJoin = require("url-join");
|
|
8
8
|
const ImageType = require("image-type");
|
|
9
9
|
const Ethers = require("ethers");
|
|
10
|
+
const Pako = require("pako");
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
/*
|
|
12
14
|
const LibraryContract = require("../contracts/BaseLibrary");
|
|
@@ -670,16 +672,18 @@ exports.CopyContentObject = async function({libraryId, originalVersionHash, opti
|
|
|
670
672
|
await Promise.all(
|
|
671
673
|
Object.keys(metadata)
|
|
672
674
|
.filter(key => key.startsWith("eluv.caps.ikms"))
|
|
673
|
-
.map(async kmsCapKey =>
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
675
|
+
.map(async kmsCapKey =>
|
|
676
|
+
await this.DeleteMetadata({
|
|
677
|
+
libraryId,
|
|
678
|
+
objectId,
|
|
679
|
+
writeToken,
|
|
680
|
+
metadataSubtree: kmsCapKey
|
|
681
|
+
})
|
|
682
|
+
)
|
|
679
683
|
);
|
|
680
684
|
|
|
681
685
|
if(permission !== "owner") {
|
|
682
|
-
await this.
|
|
686
|
+
await this.CreateEncryptionConk({libraryId, objectId, writeToken, createKMSConk: true});
|
|
683
687
|
}
|
|
684
688
|
|
|
685
689
|
return await this.FinalizeContentObject({libraryId, objectId, writeToken});
|
|
@@ -1306,6 +1310,65 @@ exports.UpdateContentObjectGraph = async function({libraryId, objectId, versionH
|
|
|
1306
1310
|
}
|
|
1307
1311
|
};
|
|
1308
1312
|
|
|
1313
|
+
/**
|
|
1314
|
+
* Generate a signed link token.
|
|
1315
|
+
*
|
|
1316
|
+
* @methodGroup Links
|
|
1317
|
+
* @namedParams
|
|
1318
|
+
* @param {string=} containerId - ID of the container object
|
|
1319
|
+
* @param {string=} versionHash - Version hash of the object
|
|
1320
|
+
* @param {string=} link - Path
|
|
1321
|
+
* @param {string=} duration - How long the link should last in milliseconds
|
|
1322
|
+
*
|
|
1323
|
+
* @return {Promise<string>} - The state channel token
|
|
1324
|
+
*/
|
|
1325
|
+
exports.GenerateSignedLinkToken = async function({
|
|
1326
|
+
containerId,
|
|
1327
|
+
versionHash,
|
|
1328
|
+
link,
|
|
1329
|
+
duration
|
|
1330
|
+
}) {
|
|
1331
|
+
ValidateObject(containerId);
|
|
1332
|
+
const canEdit = await this.CallContractMethod({
|
|
1333
|
+
contractAddress: this.utils.HashToAddress(containerId),
|
|
1334
|
+
methodName: "canEdit"
|
|
1335
|
+
});
|
|
1336
|
+
|
|
1337
|
+
const { objectId } = this.utils.DecodeVersionHash(versionHash);
|
|
1338
|
+
|
|
1339
|
+
if(!canEdit) {
|
|
1340
|
+
throw Error(`Current user does not have permission to edit content object ${objectId}`);
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
const signerAddress = this.CurrentAccountAddress();
|
|
1344
|
+
|
|
1345
|
+
let token = {
|
|
1346
|
+
adr: this.utils.B64(signerAddress.replace("0x", ""), "hex"),
|
|
1347
|
+
spc: await this.ContentSpaceId(),
|
|
1348
|
+
lib: await this.ContentObjectLibraryId({objectId}),
|
|
1349
|
+
qid: objectId,
|
|
1350
|
+
sub: `iusr${this.utils.AddressToHash(signerAddress)}`,
|
|
1351
|
+
gra: "read",
|
|
1352
|
+
iat: Date.now(),
|
|
1353
|
+
exp: duration ? (Date.now() + duration) : "",
|
|
1354
|
+
ctx: {
|
|
1355
|
+
elv: {
|
|
1356
|
+
lnk: link,
|
|
1357
|
+
src: containerId
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
};
|
|
1361
|
+
|
|
1362
|
+
const compressedToken = Pako.deflateRaw(Buffer.from(JSON.stringify(token), "utf-8"));
|
|
1363
|
+
const signature = await this.authClient.Sign(Ethers.utils.keccak256(compressedToken));
|
|
1364
|
+
|
|
1365
|
+
return `aslsjc${this.utils.B58(Buffer.concat([
|
|
1366
|
+
Buffer.from(signature.replace(/^0x/, ""), "hex"),
|
|
1367
|
+
Buffer.from(compressedToken)
|
|
1368
|
+
]))}`;
|
|
1369
|
+
};
|
|
1370
|
+
|
|
1371
|
+
|
|
1309
1372
|
/**
|
|
1310
1373
|
* Create links to files, metadata and/or representations of this or or other
|
|
1311
1374
|
* content objects.
|
|
@@ -1375,14 +1438,13 @@ exports.CreateLinks = async function({
|
|
|
1375
1438
|
});
|
|
1376
1439
|
|
|
1377
1440
|
if(linkMetadata) {
|
|
1378
|
-
link
|
|
1379
|
-
link["."] = linkMetadata["."];
|
|
1441
|
+
link = linkMetadata;
|
|
1380
1442
|
}
|
|
1381
1443
|
|
|
1382
1444
|
if(!link["."]) link["."] = {};
|
|
1383
1445
|
|
|
1384
1446
|
if(!linkMetadata["."]["authorization"]) {
|
|
1385
|
-
link["."]["authorization"] = await this.
|
|
1447
|
+
link["."]["authorization"] = await this.GenerateSignedLinkToken({
|
|
1386
1448
|
containerId: info.authContainer,
|
|
1387
1449
|
versionHash: info.targetHash,
|
|
1388
1450
|
link: `./${type}/${authTarget}`
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Methods related to notifications for the current user.
|
|
3
|
+
*
|
|
4
|
+
* @module Notifications
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const Utils = require("../Utils");
|
|
9
|
+
const UrlJoin = require("url-join");
|
|
10
|
+
|
|
11
|
+
const NotificationPath = ({network, path}) => {
|
|
12
|
+
return UrlJoin("/push", network === "main" ? "/main" : "/dv3", path);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Push a notification to the current user
|
|
17
|
+
*
|
|
18
|
+
* @methodGroup Notifications
|
|
19
|
+
* @param {string} tenantId - The tenant associated with this notification
|
|
20
|
+
* @param {string} eventType - The type of the notification
|
|
21
|
+
* @param {(Object | string)=} data - Data associated with this notification
|
|
22
|
+
*/
|
|
23
|
+
exports.PushNotification = async function({tenantId, eventType, data}) {
|
|
24
|
+
await this.stateStoreClient.Request({
|
|
25
|
+
method: "POST",
|
|
26
|
+
path: NotificationPath({network: this.network, path: UrlJoin("notify_user", this.UserAddress(), tenantId, eventType)}),
|
|
27
|
+
body: data,
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: `Bearer ${this.AuthToken()}`
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Add a listener to receive new notifications.
|
|
36
|
+
*
|
|
37
|
+
* @methodGroup Notifications
|
|
38
|
+
* @param {function} onMessage - Callback invoked when a new notification is received
|
|
39
|
+
*
|
|
40
|
+
* @returns {Promise<EventSource>} - An EventSource instance listening for notifications. Use source.close() to close the listener.
|
|
41
|
+
*/
|
|
42
|
+
exports.AddNotificationListener = async function({onMessage}) {
|
|
43
|
+
if(!onMessage) {
|
|
44
|
+
throw Error("Eluvio Wallet Client: No onMessage callback provided to AddNotificationListener");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const url = new URL(this.stateStoreClient.BaseURI().toString());
|
|
48
|
+
url.pathname = NotificationPath({network: this.network, path: UrlJoin("register", this.UserAddress(), this.AuthToken())});
|
|
49
|
+
const source = new EventSource(url);
|
|
50
|
+
source.onmessage = event => {
|
|
51
|
+
let parsedMessage = JSON.parse(event.data);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
parsedMessage.data = JSON.parse(parsedMessage.data);
|
|
55
|
+
// eslint-disable-next-line no-empty
|
|
56
|
+
} catch(error) {}
|
|
57
|
+
|
|
58
|
+
onMessage(parsedMessage);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return source;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Retrieve notifications for the current user.
|
|
66
|
+
*
|
|
67
|
+
* @methodGroup Notifications
|
|
68
|
+
* @param {integer=} limit=10 - The maximum number of notifications to return
|
|
69
|
+
* @param {string=} tenantId - Filter notifications to only those related to the specified tenant
|
|
70
|
+
* @param {Array<string>=} types - Filter notifications to only the specified types
|
|
71
|
+
* @param {string=} offsetId - Return notifications older than the specified ID
|
|
72
|
+
*
|
|
73
|
+
* @returns {Promise<Array<Object>>} - A list of notifications for the specified parameters
|
|
74
|
+
*/
|
|
75
|
+
exports.Notifications = async function({tenantId, types, offsetId, limit=10}={}) {
|
|
76
|
+
let queryParams = { limit };
|
|
77
|
+
|
|
78
|
+
if(tenantId) {
|
|
79
|
+
queryParams.tenant_id = tenantId;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if(types) {
|
|
83
|
+
queryParams.types = Array.isArray(types) ? types.join(",") : types;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if(offsetId) {
|
|
87
|
+
queryParams.offset_by = offsetId;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const {records} = await Utils.ResponseToJson(
|
|
91
|
+
this.stateStoreClient.Request({
|
|
92
|
+
method: "GET",
|
|
93
|
+
path: NotificationPath({network: this.network, path: UrlJoin("history", this.UserAddress())}),
|
|
94
|
+
queryParams,
|
|
95
|
+
headers: {
|
|
96
|
+
Authorization: `Bearer ${this.AuthToken()}`
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
return records.map(record => {
|
|
102
|
+
try {
|
|
103
|
+
record.data = JSON.parse(record.data);
|
|
104
|
+
// eslint-disable-next-line no-empty
|
|
105
|
+
} catch(error) {}
|
|
106
|
+
|
|
107
|
+
return record;
|
|
108
|
+
});
|
|
109
|
+
};
|
|
@@ -1146,5 +1146,6 @@ class ElvWalletClient {
|
|
|
1146
1146
|
|
|
1147
1147
|
Object.assign(ElvWalletClient.prototype, require("./ClientMethods"));
|
|
1148
1148
|
Object.assign(ElvWalletClient.prototype, require("./Profile"));
|
|
1149
|
+
Object.assign(ElvWalletClient.prototype, require("./Notifications"));
|
|
1149
1150
|
|
|
1150
1151
|
exports.ElvWalletClient = ElvWalletClient;
|