@eluvio/elv-client-js 4.2.21 → 4.2.23
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 +1 -1
- package/src/Crypto.js +13 -1
- package/src/ElvClient.js +1 -1
- package/src/RemoteSigner.js +71 -7
- package/src/client/ContentAccess.js +3 -3
- package/src/client/ContentManagement.js +2 -2
package/package.json
CHANGED
package/src/Crypto.js
CHANGED
|
@@ -82,7 +82,19 @@ const Crypto = {
|
|
|
82
82
|
return Utils.B64(cap);
|
|
83
83
|
},
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
// accepts either a raw private key string (legacy usage) or a signer
|
|
86
|
+
async DecryptCap(encryptedCap, signerOrPrivateKey) {
|
|
87
|
+
let privateKey;
|
|
88
|
+
if(typeof signerOrPrivateKey === "string") {
|
|
89
|
+
privateKey = signerOrPrivateKey;
|
|
90
|
+
} else if(signerOrPrivateKey && signerOrPrivateKey.remoteSigner) {
|
|
91
|
+
return await signerOrPrivateKey.DecryptCap(encryptedCap);
|
|
92
|
+
} else if(signerOrPrivateKey && typeof signerOrPrivateKey._signingKey === "function") {
|
|
93
|
+
privateKey = signerOrPrivateKey._signingKey().privateKey;
|
|
94
|
+
} else {
|
|
95
|
+
throw Error("Crypto.DecryptCap: second argument must be a signer or a private key string");
|
|
96
|
+
}
|
|
97
|
+
|
|
86
98
|
const elvCrypto = await Crypto.ElvCrypto();
|
|
87
99
|
privateKey = new Uint8Array(Buffer.from(privateKey.replace("0x", ""), "hex"));
|
|
88
100
|
|
package/src/ElvClient.js
CHANGED
|
@@ -1348,7 +1348,7 @@ class ElvClient {
|
|
|
1348
1348
|
|
|
1349
1349
|
ValidatePresence("message", message);
|
|
1350
1350
|
|
|
1351
|
-
return await this.Crypto.DecryptCap(message, this.signer
|
|
1351
|
+
return await this.Crypto.DecryptCap(message, this.signer);
|
|
1352
1352
|
}
|
|
1353
1353
|
|
|
1354
1354
|
/**
|
package/src/RemoteSigner.js
CHANGED
|
@@ -47,7 +47,7 @@ class RemoteSigner extends Ethers.Signer {
|
|
|
47
47
|
body.code = this.userIdCode;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
const {addr, eth, token} = await Utils.ResponseToJson(
|
|
50
|
+
const {addr, eth, token, pubkey} = await Utils.ResponseToJson(
|
|
51
51
|
this.HttpClient.Request({
|
|
52
52
|
path: UrlJoin("as", "wlt", "login", this.userIdCode ? "code" : "jwt"),
|
|
53
53
|
method: "POST",
|
|
@@ -61,9 +61,10 @@ class RemoteSigner extends Ethers.Signer {
|
|
|
61
61
|
this.authToken = token;
|
|
62
62
|
this.address = Utils.FormatAddress(addr);
|
|
63
63
|
this.id = eth;
|
|
64
|
+
this.publicKey = pubkey;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
if(!this.address) {
|
|
67
|
+
if(!this.address || !this.publicKey) {
|
|
67
68
|
const keys = await Utils.ResponseToJson(
|
|
68
69
|
this.HttpClient.Request({
|
|
69
70
|
method: "GET",
|
|
@@ -74,12 +75,18 @@ class RemoteSigner extends Ethers.Signer {
|
|
|
74
75
|
})
|
|
75
76
|
);
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
if(!this.address) {
|
|
79
|
+
const address = keys.eth[0];
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
if(address && address.startsWith("0x")) {
|
|
82
|
+
this.address = address;
|
|
83
|
+
} else {
|
|
84
|
+
this.address = Utils.HashToAddress(keys.eth[0]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if(!this.publicKey) {
|
|
89
|
+
this.publicKey = keys.pubkey && keys.pubkey[0];
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
92
|
|
|
@@ -170,6 +177,63 @@ class RemoteSigner extends Ethers.Signer {
|
|
|
170
177
|
return this.address;
|
|
171
178
|
}
|
|
172
179
|
|
|
180
|
+
_normalizePublicKey(key) {
|
|
181
|
+
const with0x = key.startsWith("0x") ? key : `0x${key}`;
|
|
182
|
+
return with0x.length === 2 + 128 ? `0x04${with0x.slice(2)}` : with0x;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* This signer's public key, as provided by the authd service
|
|
187
|
+
*
|
|
188
|
+
* @return {Promise<string>} - The public key, in uncompressed hex like SigningKey.publicKey
|
|
189
|
+
*/
|
|
190
|
+
async PublicKey() {
|
|
191
|
+
if(!this.publicKey) {
|
|
192
|
+
throw Error("RemoteSigner: public key not available - call Initialize() first");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return this._normalizePublicKey(this.publicKey);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** so remote signers can be used interchangeably with local signers */
|
|
199
|
+
_signingKey() {
|
|
200
|
+
if(!this.publicKey) {
|
|
201
|
+
throw Error("RemoteSigner: public key not available - call Initialize() first");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const publicKey = this._normalizePublicKey(this.publicKey);
|
|
205
|
+
return {
|
|
206
|
+
publicKey,
|
|
207
|
+
get privateKey() {
|
|
208
|
+
throw Error("RemoteSigner: remote signer does not have direct access to a private key");
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Decrypt a secp256k1 ECIES-encrypted blob (e.g. a fabric encryption conk) that was wrapped
|
|
215
|
+
* for this signer's public key, via the authd service's generic decrypt endpoint.
|
|
216
|
+
*
|
|
217
|
+
* @param {string} encryptedData - Base64-encoded ECIES-encrypted blob
|
|
218
|
+
* @return {Promise<Object>} - The decrypted, JSON-parsed contents
|
|
219
|
+
*/
|
|
220
|
+
async DecryptCap(encryptedData) {
|
|
221
|
+
const {data} = await Utils.ResponseToJson(
|
|
222
|
+
this.HttpClient.Request({
|
|
223
|
+
method: "POST",
|
|
224
|
+
path: UrlJoin("as", "wlt", "decrypt", "eth", this.id),
|
|
225
|
+
headers: {
|
|
226
|
+
Authorization: `Bearer ${this.authToken}`
|
|
227
|
+
},
|
|
228
|
+
body: {
|
|
229
|
+
data: encryptedData
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
return JSON.parse(Buffer.from(data, "base64").toString());
|
|
235
|
+
}
|
|
236
|
+
|
|
173
237
|
async signDigest(digest) {
|
|
174
238
|
if(!this.signatureCache[digest]) {
|
|
175
239
|
this.signatureCache[digest] = new Promise(async (resolve, reject) => {
|
|
@@ -2718,7 +2718,7 @@ exports.LinkData = async function({libraryId, objectId, versionHash, writeToken,
|
|
|
2718
2718
|
|
|
2719
2719
|
exports.CreateEncryptionConk = async function({libraryId, objectId, versionHash, writeToken, createKMSConk=true}) {
|
|
2720
2720
|
if(this.signer.remoteSigner) {
|
|
2721
|
-
|
|
2721
|
+
await this.signer.PublicKey();
|
|
2722
2722
|
}
|
|
2723
2723
|
|
|
2724
2724
|
ValidateParameters({libraryId, objectId, versionHash});
|
|
@@ -2743,7 +2743,7 @@ exports.CreateEncryptionConk = async function({libraryId, objectId, versionHash,
|
|
|
2743
2743
|
});
|
|
2744
2744
|
|
|
2745
2745
|
if(existingUserCap) {
|
|
2746
|
-
this.encryptionConks[objectId] = await this.Crypto.DecryptCap(existingUserCap, this.signer
|
|
2746
|
+
this.encryptionConks[objectId] = await this.Crypto.DecryptCap(existingUserCap, this.signer);
|
|
2747
2747
|
} else {
|
|
2748
2748
|
this.encryptionConks[objectId] = await this.Crypto.GeneratePrimaryConk({
|
|
2749
2749
|
spaceId: this.contentSpaceId,
|
|
@@ -2846,7 +2846,7 @@ exports.EncryptionConk = async function({libraryId, objectId, versionHash, write
|
|
|
2846
2846
|
});
|
|
2847
2847
|
|
|
2848
2848
|
if(existingUserCap) {
|
|
2849
|
-
this.encryptionConks[objectId] = await this.Crypto.DecryptCap(existingUserCap, this.signer
|
|
2849
|
+
this.encryptionConks[objectId] = await this.Crypto.DecryptCap(existingUserCap, this.signer);
|
|
2850
2850
|
} else if(writeToken) {
|
|
2851
2851
|
await this.CreateEncryptionConk({libraryId, objectId, versionHash, writeToken, createKMSConk: false});
|
|
2852
2852
|
} else {
|
|
@@ -680,7 +680,7 @@ exports.CopyContentObject = async function({libraryId, originalVersionHash, opti
|
|
|
680
680
|
const userCapKey = `eluv.caps.iusr${this.utils.AddressToHash(this.signer.address)}`;
|
|
681
681
|
|
|
682
682
|
if(metadata[userCapKey]) {
|
|
683
|
-
const userConkKey = await this.Crypto.DecryptCap(metadata[userCapKey], this.signer
|
|
683
|
+
const userConkKey = await this.Crypto.DecryptCap(metadata[userCapKey], this.signer);
|
|
684
684
|
userConkKey.qid = objectId;
|
|
685
685
|
|
|
686
686
|
await this.ReplaceMetadata({
|
|
@@ -733,7 +733,7 @@ exports.CreateNonOwnerCap = async function({objectId, libraryId, publicKey, writ
|
|
|
733
733
|
throw Error("No user cap found for current user");
|
|
734
734
|
}
|
|
735
735
|
|
|
736
|
-
const userConk = await this.Crypto.DecryptCap(userCapValue, this.signer
|
|
736
|
+
const userConk = await this.Crypto.DecryptCap(userCapValue, this.signer);
|
|
737
737
|
|
|
738
738
|
const publicAddress = this.utils.PublicKeyToAddress(publicKey);
|
|
739
739
|
|