mirror of
https://github.com/Qortal/qortal-ui.git
synced 2025-04-24 03:47:53 +00:00
added multiple publish encryption
This commit is contained in:
parent
82bfcc3b28
commit
64d6510c4b
@ -645,7 +645,8 @@
|
|||||||
"bchange42": "Items",
|
"bchange42": "Items",
|
||||||
"bchange43": "Do you give this application permission to add to this list?",
|
"bchange43": "Do you give this application permission to add to this list?",
|
||||||
"bchange44": "Do you give this application permission to delete from this list?",
|
"bchange44": "Do you give this application permission to delete from this list?",
|
||||||
"bchange45": "Encrypt"
|
"bchange45": "Encrypt",
|
||||||
|
"bchange46": "Do you give this application permission to save the following file:"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Data Management",
|
"dchange1": "Data Management",
|
||||||
|
@ -42,3 +42,6 @@ export const ENCRYPT_DATA = 'ENCRYPT_DATA'
|
|||||||
|
|
||||||
// DECRYPT_DATA
|
// DECRYPT_DATA
|
||||||
export const DECRYPT_DATA = 'DECRYPT_DATA'
|
export const DECRYPT_DATA = 'DECRYPT_DATA'
|
||||||
|
|
||||||
|
// SAVE_FILE
|
||||||
|
export const SAVE_FILE = 'SAVE_FILE'
|
@ -24,7 +24,7 @@ import { QORT_DECIMALS } from 'qortal-ui-crypto/api/constants';
|
|||||||
import nacl from '../../../../../qortal-ui-crypto/api/deps/nacl-fast.js'
|
import nacl from '../../../../../qortal-ui-crypto/api/deps/nacl-fast.js'
|
||||||
import ed2curve from '../../../../../qortal-ui-crypto/api/deps/ed2curve.js'
|
import ed2curve from '../../../../../qortal-ui-crypto/api/deps/ed2curve.js'
|
||||||
import { mimeToExtensionMap } from '../../components/qdn-action-constants';
|
import { mimeToExtensionMap } from '../../components/qdn-action-constants';
|
||||||
import { encryptData } from '../../components/qdn-action-encryption';
|
import { base64ToUint8Array, encryptData, uint8ArrayToBase64 } from '../../components/qdn-action-encryption';
|
||||||
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
|
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
|
||||||
|
|
||||||
class WebBrowser extends LitElement {
|
class WebBrowser extends LitElement {
|
||||||
@ -561,79 +561,9 @@ class WebBrowser extends LitElement {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case actions.ENCRYPT_DATA: {
|
|
||||||
const requiredFields = ['Uint8ArrayData', 'destinationPublicKey'];
|
|
||||||
const missingFields = [];
|
|
||||||
|
|
||||||
requiredFields.forEach((field) => {
|
|
||||||
if (!data[field]) {
|
|
||||||
missingFields.push(field);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (missingFields.length > 0) {
|
|
||||||
const missingFieldsString = missingFields.join(', ');
|
|
||||||
const errorMsg = `Missing fields: ${missingFieldsString}`
|
|
||||||
let data = {};
|
|
||||||
data['error'] = errorMsg;
|
|
||||||
response = JSON.stringify(data);
|
|
||||||
break
|
|
||||||
}
|
|
||||||
const { Uint8ArrayData, destinationPublicKey } = data
|
|
||||||
|
|
||||||
const uint8Array = new Uint8Array(Object.values(Uint8ArrayData));
|
|
||||||
if (!(uint8Array instanceof Uint8Array)) {
|
|
||||||
data['error'] = "The Uint8ArrayData you've submitted is invalid";
|
|
||||||
response = JSON.stringify(data);
|
|
||||||
break
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey
|
|
||||||
if (!privateKey) {
|
|
||||||
data['error'] = "Unable to retrieve keys"
|
|
||||||
response = JSON.stringify(data);
|
|
||||||
break
|
|
||||||
}
|
|
||||||
const publicKeyUnit8Array = window.parent.Base58.decode(destinationPublicKey)
|
|
||||||
|
|
||||||
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
|
|
||||||
const convertedPublicKey = ed2curve.convertPublicKey(publicKeyUnit8Array)
|
|
||||||
const sharedSecret = new Uint8Array(32)
|
|
||||||
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
|
|
||||||
|
|
||||||
const chatEncryptionSeed = new window.parent.Sha256().process(sharedSecret).finish().result
|
|
||||||
|
|
||||||
const nonce = new Uint8Array(24);
|
|
||||||
window.crypto.getRandomValues(nonce);
|
|
||||||
const encryptedData = nacl.secretbox(uint8Array, nonce, chatEncryptionSeed)
|
|
||||||
|
|
||||||
const str = "qortalEncryptedData";
|
|
||||||
const strEncoder = new TextEncoder();
|
|
||||||
const strUint8Array = strEncoder.encode(str);
|
|
||||||
|
|
||||||
const combinedData = new Uint8Array(strUint8Array.length + nonce.length + encryptedData.length);
|
|
||||||
|
|
||||||
combinedData.set(strUint8Array);
|
|
||||||
|
|
||||||
combinedData.set(nonce, strUint8Array.length);
|
|
||||||
combinedData.set(encryptedData, strUint8Array.length + nonce.length);
|
|
||||||
|
|
||||||
|
|
||||||
let data = {};
|
|
||||||
data['encryptedData'] = combinedData
|
|
||||||
data['destinationPublicKey'] = destinationPublicKey
|
|
||||||
response = JSON.stringify(data);
|
|
||||||
break;
|
|
||||||
} catch (error) {
|
|
||||||
const data = {};
|
|
||||||
const errorMsg = error.message || "Error in encrypting data"
|
|
||||||
data['error'] = errorMsg;
|
|
||||||
response = JSON.stringify(data);
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case actions.DECRYPT_DATA: {
|
case actions.DECRYPT_DATA: {
|
||||||
const requiredFields = ['encryptedData', 'senderPublicKey'];
|
const requiredFields = ['encryptedData', 'publicKey'];
|
||||||
const missingFields = [];
|
const missingFields = [];
|
||||||
|
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
@ -650,11 +580,11 @@ class WebBrowser extends LitElement {
|
|||||||
response = JSON.stringify(data);
|
response = JSON.stringify(data);
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
const { encryptedData, senderPublicKey } = data
|
const { encryptedData, publicKey } = data
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const uint8Array = new Uint8Array(Object.values(encryptedData));
|
const uint8Array = base64ToUint8Array(encryptedData)
|
||||||
const combinedData = uint8Array
|
const combinedData = uint8Array
|
||||||
const str = "qortalEncryptedData";
|
const str = "qortalEncryptedData";
|
||||||
const strEncoder = new TextEncoder();
|
const strEncoder = new TextEncoder();
|
||||||
@ -665,26 +595,27 @@ class WebBrowser extends LitElement {
|
|||||||
const _encryptedData = combinedData.slice(strUint8Array.length + 24);
|
const _encryptedData = combinedData.slice(strUint8Array.length + 24);
|
||||||
|
|
||||||
const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey
|
const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey
|
||||||
const publicKey = window.parent.Base58.decode(senderPublicKey)
|
const _publicKey = window.parent.Base58.decode(publicKey)
|
||||||
|
|
||||||
if (!privateKey || !publicKey) {
|
if (!privateKey || !_publicKey) {
|
||||||
data['error'] = "Unable to retrieve keys"
|
data['error'] = "Unable to retrieve keys"
|
||||||
response = JSON.stringify(data);
|
response = JSON.stringify(data);
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
|
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
|
||||||
const convertedPublicKey = ed2curve.convertPublicKey(publicKey)
|
const convertedPublicKey = ed2curve.convertPublicKey(_publicKey)
|
||||||
const sharedSecret = new Uint8Array(32);
|
const sharedSecret = new Uint8Array(32);
|
||||||
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
|
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
|
||||||
|
|
||||||
const _chatEncryptionSeed = new window.parent.Sha256().process(sharedSecret).finish().result
|
const _chatEncryptionSeed = new window.parent.Sha256().process(sharedSecret).finish().result
|
||||||
const _decryptedData = nacl.secretbox.open(_encryptedData, nonce, _chatEncryptionSeed)
|
const _decryptedData = nacl.secretbox.open(_encryptedData, nonce, _chatEncryptionSeed)
|
||||||
let data = {};
|
const decryptedDataToBase64 = uint8ArrayToBase64(_decryptedData)
|
||||||
data['decryptedData'] = _decryptedData
|
response = JSON.stringify(decryptedDataToBase64);
|
||||||
response = JSON.stringify(data);
|
|
||||||
break;
|
break;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log({ error })
|
||||||
const data = {};
|
const data = {};
|
||||||
const errorMsg = error.message || "Error in decrypting data"
|
const errorMsg = error.message || "Error in decrypting data"
|
||||||
data['error'] = errorMsg;
|
data['error'] = errorMsg;
|
||||||
@ -1059,6 +990,12 @@ class WebBrowser extends LitElement {
|
|||||||
response = JSON.stringify(data);
|
response = JSON.stringify(data);
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if (data.encrypt && !data.recipientPublicKey) {
|
||||||
|
let data = {};
|
||||||
|
data['error'] = "Encrypting data requires the recipient's public key";
|
||||||
|
response = JSON.stringify(data);
|
||||||
|
break
|
||||||
|
}
|
||||||
const res2 = await showModalAndWait(
|
const res2 = await showModalAndWait(
|
||||||
actions.PUBLISH_MULTIPLE_QDN_RESOURCES,
|
actions.PUBLISH_MULTIPLE_QDN_RESOURCES,
|
||||||
{
|
{
|
||||||
@ -1091,7 +1028,7 @@ class WebBrowser extends LitElement {
|
|||||||
const service = resource.service;
|
const service = resource.service;
|
||||||
const name = resource.name;
|
const name = resource.name;
|
||||||
let identifier = resource.identifier;
|
let identifier = resource.identifier;
|
||||||
const data64 = resource.data64;
|
let data64 = resource.data64;
|
||||||
const filename = resource.filename;
|
const filename = resource.filename;
|
||||||
const title = resource.title;
|
const title = resource.title;
|
||||||
const description = resource.description;
|
const description = resource.description;
|
||||||
@ -1105,6 +1042,24 @@ class WebBrowser extends LitElement {
|
|||||||
identifier = 'default';
|
identifier = 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.encrypt) {
|
||||||
|
try {
|
||||||
|
const encryptDataResponse = encryptData({
|
||||||
|
data64, recipientPublicKey: data.recipientPublicKey
|
||||||
|
})
|
||||||
|
if (encryptDataResponse.encryptedData) {
|
||||||
|
data64 = encryptDataResponse.encryptedData
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
const errorMsg = error.message || 'Upload failed due to failed encryption'
|
||||||
|
throw new Error(errorMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const worker = new WebWorker();
|
const worker = new WebWorker();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@ -1422,8 +1377,9 @@ class WebBrowser extends LitElement {
|
|||||||
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'DOWNLOAD': {
|
case actions.SAVE_FILE: {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const requiredFields = ['filename', 'blob'];
|
const requiredFields = ['filename', 'blob'];
|
||||||
const missingFields = [];
|
const missingFields = [];
|
||||||
|
|
||||||
@ -1442,9 +1398,24 @@ class WebBrowser extends LitElement {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const filename = data.filename
|
const filename = data.filename
|
||||||
const blob = data.blob
|
const blob = data.blob
|
||||||
|
|
||||||
|
const res = await showModalAndWait(
|
||||||
|
actions.SAVE_FILE,
|
||||||
|
{
|
||||||
|
filename
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res.action === 'reject') {
|
||||||
|
response = '{"error": "User declined request"}';
|
||||||
|
break
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const mimeType = blob.type || data.mimeType
|
const mimeType = blob.type || data.mimeType
|
||||||
let backupExention = filename.split('.').pop()
|
let backupExention = filename.split('.').pop()
|
||||||
if (backupExention) {
|
if (backupExention) {
|
||||||
@ -2952,6 +2923,12 @@ async function showModalAndWait(type, data) {
|
|||||||
<p class="modal-paragraph">${get("browserpage.bchange42")}: <span> ${data.items.join(', ')}</span></p>
|
<p class="modal-paragraph">${get("browserpage.bchange42")}: <span> ${data.items.join(', ')}</span></p>
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
|
${type === actions.SAVE_FILE ? `
|
||||||
|
<div class="modal-subcontainer">
|
||||||
|
<p class="modal-paragraph">${get("browserpage.bchange46")}: <span> ${data.filename}</span></p>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
${type === actions.DELETE_LIST_ITEM ? `
|
${type === actions.DELETE_LIST_ITEM ? `
|
||||||
<div class="modal-subcontainer">
|
<div class="modal-subcontainer">
|
||||||
<p class="modal-paragraph">${get("browserpage.bchange44")}</p>
|
<p class="modal-paragraph">${get("browserpage.bchange44")}</p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user