From bc5031c1949ce497540088c75b6f7fd7c5c4d305 Mon Sep 17 00:00:00 2001 From: Phillip Date: Fri, 12 May 2023 14:53:55 +0300 Subject: [PATCH 01/27] initial working code for group encryption --- .../core/components/qdn-action-encryption.js | 99 ++++++++++++- .../core/components/qdn-action-types.js | 3 + .../plugins/core/qdn/browser/browser.src.js | 135 +++++++++++++++++- 3 files changed, 234 insertions(+), 3 deletions(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index 98b26c67..f7446651 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -101,4 +101,101 @@ export const encryptData = ({ data64, recipientPublicKey }) => { console.log({ error }) throw new Error("Error in encrypting data") } -} \ No newline at end of file +} + +export const encryptDataGroup = ({ data64, recipientPublicKeys }) => { + console.log({ recipientPublicKeys, data64 }) + const Uint8ArrayData = base64ToUint8Array(data64) + + if (!(Uint8ArrayData instanceof Uint8Array)) { + throw new Error("The Uint8ArrayData you've submitted is invalid") + } + + try { + const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey + if (!privateKey) { + throw new Error("Unable to retrieve keys") + } + + // Generate a random symmetric key for the message. + const messageKey = new Uint8Array(32); + window.crypto.getRandomValues(messageKey); + + // Encrypt the message with the symmetric key. + const nonce = new Uint8Array(24); + window.crypto.getRandomValues(nonce); + + const encryptedData = nacl.secretbox(Uint8ArrayData, nonce, messageKey); + console.log('front', { encryptedData }) + // Encrypt the symmetric key for each recipient. + let encryptedKeys = []; + recipientPublicKeys.forEach((recipientPublicKey) => { + const publicKeyUnit8Array = window.parent.Base58.decode(recipientPublicKey) + + const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) + const convertedPublicKey = ed2curve.convertPublicKey(publicKeyUnit8Array) + + const sharedSecret = new Uint8Array(32) + nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) + + // Encrypt the symmetric key with the shared secret. + const keyNonce = new Uint8Array(24); + window.crypto.getRandomValues(keyNonce); + const encryptedKey = nacl.secretbox(messageKey, keyNonce, sharedSecret); + + console.log('100', { keyNonce, recipientPublicKey, encryptedKey }) + + encryptedKeys.push({ + recipientPublicKey, + keyNonce, + encryptedKey + }); + }); + + const str = "qortalEncryptedData"; + const strEncoder = new TextEncoder(); + const strUint8Array = strEncoder.encode(str); + console.log('hello4') + // Combine all data into a single Uint8Array. + // Calculate size of combinedData + let combinedDataSize = strUint8Array.length + nonce.length + encryptedData.length + 4; + let encryptedKeysSize = 0; + + encryptedKeys.forEach((key) => { + encryptedKeysSize += key.keyNonce.length + key.encryptedKey.length; + }); + + combinedDataSize += encryptedKeysSize; + + let combinedData = new Uint8Array(combinedDataSize); + + combinedData.set(strUint8Array); + combinedData.set(nonce, strUint8Array.length); + combinedData.set(encryptedData, strUint8Array.length + nonce.length); + console.log('encrypt start', strUint8Array.length + nonce.length) + console.log('encryptedLength2', encryptedData.length) + // Initialize offset for encryptedKeys + let encryptedKeysOffset = strUint8Array.length + nonce.length + encryptedData.length; + console.log('encrypt end', encryptedKeysOffset) + encryptedKeys.forEach((key) => { + combinedData.set(key.keyNonce, encryptedKeysOffset); + console.log('key.keyNonce', key.keyNonce.length) + encryptedKeysOffset += key.keyNonce.length; + + combinedData.set(key.encryptedKey, encryptedKeysOffset); + console.log('key.encryptedKey', key.encryptedKey.length) + encryptedKeysOffset += key.encryptedKey.length; + }); + const countArray = new Uint8Array(new Uint32Array([recipientPublicKeys.length]).buffer); + console.log({ countArray }) + combinedData.set(countArray, combinedData.length - 4); + console.log('totalLength 2', combinedData.length) + const uint8arrayToData64 = uint8ArrayToBase64(combinedData) + + return uint8arrayToData64; + + } catch (error) { + console.log({ error }) + throw new Error("Error in encrypting data") + } +} diff --git a/plugins/plugins/core/components/qdn-action-types.js b/plugins/plugins/core/components/qdn-action-types.js index 666d67f2..f4eb4f16 100644 --- a/plugins/plugins/core/components/qdn-action-types.js +++ b/plugins/plugins/core/components/qdn-action-types.js @@ -43,5 +43,8 @@ export const ENCRYPT_DATA = 'ENCRYPT_DATA' // DECRYPT_DATA export const DECRYPT_DATA = 'DECRYPT_DATA' +// DECRYPT_DATA_GROUP +export const DECRYPT_DATA_GROUP = 'DECRYPT_DATA_GROUP' + // SAVE_FILE export const SAVE_FILE = 'SAVE_FILE' \ No newline at end of file diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index c01bd5d5..494a566c 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -24,7 +24,7 @@ import { QORT_DECIMALS } from '../../../../../crypto/api/constants'; import nacl from '../../../../../crypto/api/deps/nacl-fast.js' import ed2curve from '../../../../../crypto/api/deps/ed2curve.js' import { mimeToExtensionMap } from '../../components/qdn-action-constants'; -import { base64ToUint8Array, encryptData, fileToBase64, uint8ArrayToBase64 } from '../../components/qdn-action-encryption'; +import { base64ToUint8Array, encryptData, encryptDataGroup, fileToBase64, uint8ArrayToBase64 } from '../../components/qdn-action-encryption'; const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }); class WebBrowser extends LitElement { @@ -623,6 +623,118 @@ class WebBrowser extends LitElement { break } } + + case actions.DECRYPT_DATA_GROUP: { + const requiredFields = ['encryptedData', 'publicKeys']; + 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 { encryptedData: data64EncryptedData, publicKeys } = data + console.log({ publicKeys, data64EncryptedData }) + try { + const allCombined = base64ToUint8Array(data64EncryptedData); + console.log('total length', allCombined.length) + const str = "qortalEncryptedData"; + const strEncoder = new TextEncoder(); + const strUint8Array = strEncoder.encode(str); + + // Extract the nonce + const nonceStartPosition = strUint8Array.length; + const nonceEndPosition = nonceStartPosition + 24; // Nonce is 24 bytes + const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition); + + // Calculate count first + const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes) + const countArray = allCombined.slice(countStartPosition, countStartPosition + 4); + console.log({ countArray }) + const count = new Uint32Array(countArray.buffer)[0]; + console.log({ count }) + + // Then use count to calculate encryptedData + const encryptedDataStartPosition = nonceEndPosition; // start position of encryptedData + console.log({ encryptedDataStartPosition }) + const encryptedDataEndPosition = allCombined.length - ((count * (24 + 32 + 16)) + 4); + console.log({ encryptedDataEndPosition }) + const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition); + console.log('back', { encryptedData }) + console.log({ encryptedLength: encryptedData.length }) + + // Extract the encrypted keys + const combinedKeys = allCombined.slice(encryptedDataEndPosition, encryptedDataEndPosition + (count * (24 + 48))); + + const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey + const senderPublicKey = window.parent.Base58.decode(publicKeys[0]) // Assuming the sender's public key is the first one + + if (!privateKey || !senderPublicKey) { + data['error'] = "Unable to retrieve keys" + response = JSON.stringify(data); + break + } + + const recipientPrivateKeyUint8Array = privateKey + const senderPublicKeyUint8Array = senderPublicKey + + const convertedPrivateKey = ed2curve.convertSecretKey(recipientPrivateKeyUint8Array) + const convertedPublicKey = ed2curve.convertPublicKey(senderPublicKeyUint8Array) + + const sharedSecret = new Uint8Array(32) + nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) + console.log({ sharedSecret }) + for (let i = 0; i < count; i++) { + const keyNonce = combinedKeys.slice(i * (24 + 48), i * (24 + 48) + 24); + const encryptedKey = combinedKeys.slice(i * (24 + 48) + 24, (i + 1) * (24 + 48)); + console.log({ keyNonce, encryptedKey }) + // Decrypt the symmetric key. + const decryptedKey = nacl.secretbox.open(encryptedKey, keyNonce, sharedSecret); + console.log({ decryptedKey }) + + // If decryption was successful, decryptedKey will not be null. + if (decryptedKey) { + // Decrypt the data using the symmetric key. + const decryptedData = nacl.secretbox.open(encryptedData, nonce, decryptedKey); + + // If decryption was successful, decryptedData will not be null. + if (decryptedData) { + console.log({ decryptedData }) + const decryptedDataToBase64 = uint8ArrayToBase64(decryptedData) + console.log({ decryptedDataToBase64 }) + + response = JSON.stringify(decryptedDataToBase64); + + break; + } + } + } + + if (!response) { + const data = {}; + data['error'] = "Unable to decrypt data"; + response = JSON.stringify(data); + } + } catch (error) { + console.log({ error }) + const data = {}; + const errorMsg = error.message || "Error in decrypting data" + data['error'] = errorMsg; + response = JSON.stringify(data); + } + break; + } + case actions.GET_LIST_ITEMS: { const requiredFields = ['list_name']; const missingFields = []; @@ -895,7 +1007,7 @@ class WebBrowser extends LitElement { break } - if (data.encrypt) { + if (data.encrypt && (!data.type || data.type !== 'group')) { try { const encryptDataResponse = encryptData({ data64, recipientPublicKey: data.recipientPublicKey @@ -913,6 +1025,25 @@ class WebBrowser extends LitElement { } } + if (data.encrypt && data.type && data.type === 'group') { + try { + const encryptDataResponse = encryptDataGroup({ + data64, recipientPublicKeys: data.recipientPublicKeys + }) + if (encryptDataResponse) { + data64 = encryptDataResponse + } + + } catch (error) { + const obj = {}; + const errorMsg = error.message || 'Upload failed due to failed encryption'; + obj['error'] = errorMsg; + response = JSON.stringify(obj); + break + } + + } + const res2 = await showModalAndWait( From 53a3e0e183fa7604fc4d4e09703ba2f2b19f63a9 Mon Sep 17 00:00:00 2001 From: Phillip Date: Fri, 12 May 2023 23:09:15 +0300 Subject: [PATCH 02/27] clean up code --- .../core/components/qdn-action-encryption.js | 29 ++++------ .../plugins/core/qdn/browser/browser.src.js | 57 ++++--------------- 2 files changed, 22 insertions(+), 64 deletions(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index f7446651..742b4610 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -103,8 +103,8 @@ export const encryptData = ({ data64, recipientPublicKey }) => { } } -export const encryptDataGroup = ({ data64, recipientPublicKeys }) => { - console.log({ recipientPublicKeys, data64 }) +export const encryptDataGroup = ({ data64, publicKeys }) => { + const publicKeysDuplicateFree = [...new Set(publicKeys)]; const Uint8ArrayData = base64ToUint8Array(data64) if (!(Uint8ArrayData instanceof Uint8Array)) { @@ -121,15 +121,15 @@ export const encryptDataGroup = ({ data64, recipientPublicKeys }) => { const messageKey = new Uint8Array(32); window.crypto.getRandomValues(messageKey); - // Encrypt the message with the symmetric key. const nonce = new Uint8Array(24); window.crypto.getRandomValues(nonce); + // Encrypt the data with the symmetric key. const encryptedData = nacl.secretbox(Uint8ArrayData, nonce, messageKey); - console.log('front', { encryptedData }) + // Encrypt the symmetric key for each recipient. let encryptedKeys = []; - recipientPublicKeys.forEach((recipientPublicKey) => { + publicKeysDuplicateFree.forEach((recipientPublicKey) => { const publicKeyUnit8Array = window.parent.Base58.decode(recipientPublicKey) const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) @@ -138,12 +138,12 @@ export const encryptDataGroup = ({ data64, recipientPublicKeys }) => { const sharedSecret = new Uint8Array(32) nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) - // Encrypt the symmetric key with the shared secret. + const keyNonce = new Uint8Array(24); window.crypto.getRandomValues(keyNonce); - const encryptedKey = nacl.secretbox(messageKey, keyNonce, sharedSecret); - console.log('100', { keyNonce, recipientPublicKey, encryptedKey }) + // Encrypt the symmetric key with the shared secret. + const encryptedKey = nacl.secretbox(messageKey, keyNonce, sharedSecret); encryptedKeys.push({ recipientPublicKey, @@ -155,7 +155,7 @@ export const encryptDataGroup = ({ data64, recipientPublicKeys }) => { const str = "qortalEncryptedData"; const strEncoder = new TextEncoder(); const strUint8Array = strEncoder.encode(str); - console.log('hello4') + // Combine all data into a single Uint8Array. // Calculate size of combinedData let combinedDataSize = strUint8Array.length + nonce.length + encryptedData.length + 4; @@ -172,30 +172,23 @@ export const encryptDataGroup = ({ data64, recipientPublicKeys }) => { combinedData.set(strUint8Array); combinedData.set(nonce, strUint8Array.length); combinedData.set(encryptedData, strUint8Array.length + nonce.length); - console.log('encrypt start', strUint8Array.length + nonce.length) - console.log('encryptedLength2', encryptedData.length) + // Initialize offset for encryptedKeys let encryptedKeysOffset = strUint8Array.length + nonce.length + encryptedData.length; - console.log('encrypt end', encryptedKeysOffset) encryptedKeys.forEach((key) => { combinedData.set(key.keyNonce, encryptedKeysOffset); - console.log('key.keyNonce', key.keyNonce.length) encryptedKeysOffset += key.keyNonce.length; combinedData.set(key.encryptedKey, encryptedKeysOffset); - console.log('key.encryptedKey', key.encryptedKey.length) encryptedKeysOffset += key.encryptedKey.length; }); - const countArray = new Uint8Array(new Uint32Array([recipientPublicKeys.length]).buffer); - console.log({ countArray }) + const countArray = new Uint8Array(new Uint32Array([publicKeysDuplicateFree.length]).buffer); combinedData.set(countArray, combinedData.length - 4); - console.log('totalLength 2', combinedData.length) const uint8arrayToData64 = uint8ArrayToBase64(combinedData) return uint8arrayToData64; } catch (error) { - console.log({ error }) throw new Error("Error in encrypting data") } } diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index 494a566c..effadb7e 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -625,7 +625,7 @@ class WebBrowser extends LitElement { } case actions.DECRYPT_DATA_GROUP: { - const requiredFields = ['encryptedData', 'publicKeys']; + const requiredFields = ['encryptedData']; const missingFields = []; requiredFields.forEach((field) => { @@ -643,11 +643,9 @@ class WebBrowser extends LitElement { break } - const { encryptedData: data64EncryptedData, publicKeys } = data - console.log({ publicKeys, data64EncryptedData }) + const { encryptedData: data64EncryptedData } = data try { const allCombined = base64ToUint8Array(data64EncryptedData); - console.log('total length', allCombined.length) const str = "qortalEncryptedData"; const strEncoder = new TextEncoder(); const strUint8Array = strEncoder.encode(str); @@ -660,47 +658,35 @@ class WebBrowser extends LitElement { // Calculate count first const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes) const countArray = allCombined.slice(countStartPosition, countStartPosition + 4); - console.log({ countArray }) const count = new Uint32Array(countArray.buffer)[0]; - console.log({ count }) // Then use count to calculate encryptedData const encryptedDataStartPosition = nonceEndPosition; // start position of encryptedData - console.log({ encryptedDataStartPosition }) const encryptedDataEndPosition = allCombined.length - ((count * (24 + 32 + 16)) + 4); - console.log({ encryptedDataEndPosition }) const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition); - console.log('back', { encryptedData }) - console.log({ encryptedLength: encryptedData.length }) // Extract the encrypted keys const combinedKeys = allCombined.slice(encryptedDataEndPosition, encryptedDataEndPosition + (count * (24 + 48))); const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey - const senderPublicKey = window.parent.Base58.decode(publicKeys[0]) // Assuming the sender's public key is the first one + const publicKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.publicKey - if (!privateKey || !senderPublicKey) { + if (!privateKey || !publicKey) { data['error'] = "Unable to retrieve keys" response = JSON.stringify(data); break } - const recipientPrivateKeyUint8Array = privateKey - const senderPublicKeyUint8Array = senderPublicKey - - const convertedPrivateKey = ed2curve.convertSecretKey(recipientPrivateKeyUint8Array) - const convertedPublicKey = ed2curve.convertPublicKey(senderPublicKeyUint8Array) + const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) + const convertedPublicKey = ed2curve.convertPublicKey(publicKey) const sharedSecret = new Uint8Array(32) nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) - console.log({ sharedSecret }) for (let i = 0; i < count; i++) { const keyNonce = combinedKeys.slice(i * (24 + 48), i * (24 + 48) + 24); const encryptedKey = combinedKeys.slice(i * (24 + 48) + 24, (i + 1) * (24 + 48)); - console.log({ keyNonce, encryptedKey }) // Decrypt the symmetric key. const decryptedKey = nacl.secretbox.open(encryptedKey, keyNonce, sharedSecret); - console.log({ decryptedKey }) // If decryption was successful, decryptedKey will not be null. if (decryptedKey) { @@ -709,12 +695,8 @@ class WebBrowser extends LitElement { // If decryption was successful, decryptedData will not be null. if (decryptedData) { - console.log({ decryptedData }) const decryptedDataToBase64 = uint8ArrayToBase64(decryptedData) - console.log({ decryptedDataToBase64 }) - response = JSON.stringify(decryptedDataToBase64); - break; } } @@ -952,6 +934,7 @@ class WebBrowser extends LitElement { return; case actions.PUBLISH_QDN_RESOURCE: { + console.log({ data }) // optional fields: encrypt:boolean recipientPublicKey:string const requiredFields = ['service', 'name']; const missingFields = []; @@ -994,9 +977,9 @@ class WebBrowser extends LitElement { identifier = 'default'; } - if (data.encrypt && !data.recipientPublicKey) { + if (data.encrypt && (!data.publicKeys || (Array.isArray(data.publicKeys) && data.publicKeys.length === 0))) { let data = {}; - data['error'] = "Encrypting data requires the recipient's public key"; + data['error'] = "Encrypting data requires public keys"; response = JSON.stringify(data); break } @@ -1007,28 +990,10 @@ class WebBrowser extends LitElement { break } - if (data.encrypt && (!data.type || data.type !== 'group')) { - try { - const encryptDataResponse = encryptData({ - data64, recipientPublicKey: data.recipientPublicKey - }) - if (encryptDataResponse.encryptedData) { - data64 = encryptDataResponse.encryptedData - } - - } catch (error) { - const obj = {}; - const errorMsg = error.message || 'Upload failed due to failed encryption'; - obj['error'] = errorMsg; - response = JSON.stringify(obj); - break - } - - } - if (data.encrypt && data.type && data.type === 'group') { + if (data.encrypt) { try { const encryptDataResponse = encryptDataGroup({ - data64, recipientPublicKeys: data.recipientPublicKeys + data64, publicKeys: data.publicKeys }) if (encryptDataResponse) { data64 = encryptDataResponse From 52d2f67e214031a1c4365fbefe979b8c16f13261 Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 13 May 2023 01:47:40 +0300 Subject: [PATCH 03/27] only one nonce --- .../core/components/qdn-action-encryption.js | 56 ++++++++++++------- .../plugins/core/qdn/browser/browser.src.js | 24 ++++---- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index 742b4610..d91fd4b5 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -127,6 +127,10 @@ export const encryptDataGroup = ({ data64, publicKeys }) => { // Encrypt the data with the symmetric key. const encryptedData = nacl.secretbox(Uint8ArrayData, nonce, messageKey); + // Generate a keyNonce outside of the loop. + const keyNonce = new Uint8Array(24); + window.crypto.getRandomValues(keyNonce); + // Encrypt the symmetric key for each recipient. let encryptedKeys = []; publicKeysDuplicateFree.forEach((recipientPublicKey) => { @@ -136,20 +140,15 @@ export const encryptDataGroup = ({ data64, publicKeys }) => { const convertedPublicKey = ed2curve.convertPublicKey(publicKeyUnit8Array) const sharedSecret = new Uint8Array(32) + // the length of the sharedSecret will be 32 + 16 + // When you're encrypting data using nacl.secretbox, it's adding an authentication tag to the result, which is 16 bytes long. This tag is used for verifying the integrity and authenticity of the data when it is decrypted + nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) - - const keyNonce = new Uint8Array(24); - window.crypto.getRandomValues(keyNonce); - // Encrypt the symmetric key with the shared secret. const encryptedKey = nacl.secretbox(messageKey, keyNonce, sharedSecret); - encryptedKeys.push({ - recipientPublicKey, - keyNonce, - encryptedKey - }); + encryptedKeys.push(encryptedKey); }); const str = "qortalEncryptedData"; @@ -158,11 +157,11 @@ export const encryptDataGroup = ({ data64, publicKeys }) => { // Combine all data into a single Uint8Array. // Calculate size of combinedData - let combinedDataSize = strUint8Array.length + nonce.length + encryptedData.length + 4; + let combinedDataSize = strUint8Array.length + nonce.length + keyNonce.length + encryptedData.length + 4; let encryptedKeysSize = 0; encryptedKeys.forEach((key) => { - encryptedKeysSize += key.keyNonce.length + key.encryptedKey.length; + encryptedKeysSize += key.length; }); combinedDataSize += encryptedKeysSize; @@ -171,24 +170,43 @@ export const encryptDataGroup = ({ data64, publicKeys }) => { combinedData.set(strUint8Array); combinedData.set(nonce, strUint8Array.length); - combinedData.set(encryptedData, strUint8Array.length + nonce.length); + combinedData.set(keyNonce, strUint8Array.length + nonce.length); + combinedData.set(encryptedData, strUint8Array.length + nonce.length + keyNonce.length); // Initialize offset for encryptedKeys - let encryptedKeysOffset = strUint8Array.length + nonce.length + encryptedData.length; + let encryptedKeysOffset = strUint8Array.length + nonce.length + encryptedData.length + keyNonce.length; encryptedKeys.forEach((key) => { - combinedData.set(key.keyNonce, encryptedKeysOffset); - encryptedKeysOffset += key.keyNonce.length; - - combinedData.set(key.encryptedKey, encryptedKeysOffset); - encryptedKeysOffset += key.encryptedKey.length; + combinedData.set(key, encryptedKeysOffset); + encryptedKeysOffset += key.length; }); const countArray = new Uint8Array(new Uint32Array([publicKeysDuplicateFree.length]).buffer); combinedData.set(countArray, combinedData.length - 4); const uint8arrayToData64 = uint8ArrayToBase64(combinedData) - return uint8arrayToData64; } catch (error) { throw new Error("Error in encrypting data") } } + + +export function uint8ArrayStartsWith(uint8Array, string) { + const stringEncoder = new TextEncoder(); + const stringUint8Array = stringEncoder.encode(string); + + if (uint8Array.length < stringUint8Array.length) { + return false; + } + + for (let i = 0; i < stringUint8Array.length; i++) { + if (uint8Array[i] !== stringUint8Array[i]) { + return false; + } + } + + return true; +} + +export function decryptDeprecatedSingle() { + +} \ No newline at end of file diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index effadb7e..13f20f8e 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -24,7 +24,7 @@ import { QORT_DECIMALS } from '../../../../../crypto/api/constants'; import nacl from '../../../../../crypto/api/deps/nacl-fast.js' import ed2curve from '../../../../../crypto/api/deps/ed2curve.js' import { mimeToExtensionMap } from '../../components/qdn-action-constants'; -import { base64ToUint8Array, encryptData, encryptDataGroup, fileToBase64, uint8ArrayToBase64 } from '../../components/qdn-action-encryption'; +import { base64ToUint8Array, encryptData, encryptDataGroup, fileToBase64, uint8ArrayStartsWith, uint8ArrayToBase64 } from '../../components/qdn-action-encryption'; const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }); class WebBrowser extends LitElement { @@ -585,6 +585,8 @@ class WebBrowser extends LitElement { try { const uint8Array = base64ToUint8Array(encryptedData) + const startsWithQortalEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalEncryptedData"); + const startsWithQortalGroupEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalGroupEncryptedData"); const combinedData = uint8Array const str = "qortalEncryptedData"; const strEncoder = new TextEncoder(); @@ -642,7 +644,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(data); break } - const { encryptedData: data64EncryptedData } = data try { const allCombined = base64ToUint8Array(data64EncryptedData); @@ -655,19 +656,24 @@ class WebBrowser extends LitElement { const nonceEndPosition = nonceStartPosition + 24; // Nonce is 24 bytes const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition); + // Extract the shared keyNonce + const keyNonceStartPosition = nonceEndPosition; + const keyNonceEndPosition = keyNonceStartPosition + 24; // Nonce is 24 bytes + const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition); + // Calculate count first const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes) const countArray = allCombined.slice(countStartPosition, countStartPosition + 4); const count = new Uint32Array(countArray.buffer)[0]; // Then use count to calculate encryptedData - const encryptedDataStartPosition = nonceEndPosition; // start position of encryptedData - const encryptedDataEndPosition = allCombined.length - ((count * (24 + 32 + 16)) + 4); + const encryptedDataStartPosition = keyNonceEndPosition; // start position of encryptedData + const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4); const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition); // Extract the encrypted keys - const combinedKeys = allCombined.slice(encryptedDataEndPosition, encryptedDataEndPosition + (count * (24 + 48))); - + // 32+16 = 48 + const combinedKeys = allCombined.slice(encryptedDataEndPosition, encryptedDataEndPosition + (count * 48)); const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey const publicKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.publicKey @@ -679,15 +685,12 @@ class WebBrowser extends LitElement { const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) const convertedPublicKey = ed2curve.convertPublicKey(publicKey) - const sharedSecret = new Uint8Array(32) nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) for (let i = 0; i < count; i++) { - const keyNonce = combinedKeys.slice(i * (24 + 48), i * (24 + 48) + 24); - const encryptedKey = combinedKeys.slice(i * (24 + 48) + 24, (i + 1) * (24 + 48)); + const encryptedKey = combinedKeys.slice(i * 48, (i + 1) * 48); // Decrypt the symmetric key. const decryptedKey = nacl.secretbox.open(encryptedKey, keyNonce, sharedSecret); - // If decryption was successful, decryptedKey will not be null. if (decryptedKey) { // Decrypt the data using the symmetric key. @@ -934,7 +937,6 @@ class WebBrowser extends LitElement { return; case actions.PUBLISH_QDN_RESOURCE: { - console.log({ data }) // optional fields: encrypt:boolean recipientPublicKey:string const requiredFields = ['service', 'name']; const missingFields = []; From cb9d5e44a938b03c02fd1f390459c35544dc1859 Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 13 May 2023 02:47:32 +0300 Subject: [PATCH 04/27] added string check --- .../core/components/qdn-action-encryption.js | 94 +++++++++- .../plugins/core/qdn/browser/browser.src.js | 174 ++++-------------- 2 files changed, 131 insertions(+), 137 deletions(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index d91fd4b5..3a3adfb6 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -207,6 +207,98 @@ export function uint8ArrayStartsWith(uint8Array, string) { return true; } -export function decryptDeprecatedSingle() { +export function decryptDeprecatedSingle(uint8Array, publicKey) { + const combinedData = uint8Array + const str = "qortalEncryptedData"; + const strEncoder = new TextEncoder(); + const strUint8Array = strEncoder.encode(str); + const strData = combinedData.slice(0, strUint8Array.length); + const nonce = combinedData.slice(strUint8Array.length, strUint8Array.length + 24); + const _encryptedData = combinedData.slice(strUint8Array.length + 24); + + const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey + const _publicKey = window.parent.Base58.decode(publicKey) + + if (!privateKey || !_publicKey) { + + throw new Error("Unable to retrieve keys") + } + + const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) + const convertedPublicKey = ed2curve.convertPublicKey(_publicKey) + const sharedSecret = new Uint8Array(32); + nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) + + const _chatEncryptionSeed = new window.parent.Sha256().process(sharedSecret).finish().result + const _decryptedData = nacl.secretbox.open(_encryptedData, nonce, _chatEncryptionSeed) + if (!_decryptedData) { + throw new Error("Unable to decrypt") + } + const decryptedDataToBase64 = uint8ArrayToBase64(_decryptedData) + return decryptedDataToBase64 +} + +export function decryptGroupData(data64EncryptedData) { + const allCombined = base64ToUint8Array(data64EncryptedData); + const str = "qortalEncryptedData"; + const strEncoder = new TextEncoder(); + const strUint8Array = strEncoder.encode(str); + + // Extract the nonce + const nonceStartPosition = strUint8Array.length; + const nonceEndPosition = nonceStartPosition + 24; // Nonce is 24 bytes + const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition); + + // Extract the shared keyNonce + const keyNonceStartPosition = nonceEndPosition; + const keyNonceEndPosition = keyNonceStartPosition + 24; // Nonce is 24 bytes + const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition); + + // Calculate count first + const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes) + const countArray = allCombined.slice(countStartPosition, countStartPosition + 4); + const count = new Uint32Array(countArray.buffer)[0]; + + // Then use count to calculate encryptedData + const encryptedDataStartPosition = keyNonceEndPosition; // start position of encryptedData + const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4); + const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition); + + // Extract the encrypted keys + // 32+16 = 48 + const combinedKeys = allCombined.slice(encryptedDataEndPosition, encryptedDataEndPosition + (count * 48)); + const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey + const publicKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.publicKey + + if (!privateKey || !publicKey) { + throw new Error("Unable to retrieve keys") + } + + const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) + const convertedPublicKey = ed2curve.convertPublicKey(publicKey) + const sharedSecret = new Uint8Array(32) + nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) + for (let i = 0; i < count; i++) { + const encryptedKey = combinedKeys.slice(i * 48, (i + 1) * 48); + // Decrypt the symmetric key. + const decryptedKey = nacl.secretbox.open(encryptedKey, keyNonce, sharedSecret); + // If decryption was successful, decryptedKey will not be null. + if (decryptedKey) { + // Decrypt the data using the symmetric key. + const decryptedData = nacl.secretbox.open(encryptedData, nonce, decryptedKey); + + // If decryption was successful, decryptedData will not be null. + if (decryptedData) { + console.log({ decryptedData }) + return decryptedData + + } + } + } + + if (!response) { + throw new Erorr("Unable to decrypt data") + + } } \ No newline at end of file diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index 13f20f8e..f04aa31c 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -24,7 +24,7 @@ import { QORT_DECIMALS } from '../../../../../crypto/api/constants'; import nacl from '../../../../../crypto/api/deps/nacl-fast.js' import ed2curve from '../../../../../crypto/api/deps/ed2curve.js' import { mimeToExtensionMap } from '../../components/qdn-action-constants'; -import { base64ToUint8Array, encryptData, encryptDataGroup, fileToBase64, uint8ArrayStartsWith, uint8ArrayToBase64 } from '../../components/qdn-action-encryption'; +import { base64ToUint8Array, decryptDeprecatedSingle, decryptGroupData, encryptData, encryptDataGroup, fileToBase64, uint8ArrayStartsWith, uint8ArrayToBase64 } from '../../components/qdn-action-encryption'; const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }); class WebBrowser extends LitElement { @@ -563,161 +563,63 @@ class WebBrowser extends LitElement { } case actions.DECRYPT_DATA: { - const requiredFields = ['encryptedData', 'publicKey']; - 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 { encryptedData, publicKey } = data try { + let data = {}; + if (!encryptedData) { + const errorMsg = `Missing fields: encryptedData` + + data['error'] = errorMsg; + response = JSON.stringify(data); + break + + } const uint8Array = base64ToUint8Array(encryptedData) const startsWithQortalEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalEncryptedData"); - const startsWithQortalGroupEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalGroupEncryptedData"); - const combinedData = uint8Array - const str = "qortalEncryptedData"; - const strEncoder = new TextEncoder(); - const strUint8Array = strEncoder.encode(str); - const strData = combinedData.slice(0, strUint8Array.length); - const nonce = combinedData.slice(strUint8Array.length, strUint8Array.length + 24); - const _encryptedData = combinedData.slice(strUint8Array.length + 24); + if (startsWithQortalEncryptedData) { - const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey - const _publicKey = window.parent.Base58.decode(publicKey) + if (!publicKey) { + const errorMsg = `Missing fields: publicKey` - if (!privateKey || !_publicKey) { - data['error'] = "Unable to retrieve keys" - response = JSON.stringify(data); - break - } - - const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) - const convertedPublicKey = ed2curve.convertPublicKey(_publicKey) - const sharedSecret = new Uint8Array(32); - nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) - - const _chatEncryptionSeed = new window.parent.Sha256().process(sharedSecret).finish().result - const _decryptedData = nacl.secretbox.open(_encryptedData, nonce, _chatEncryptionSeed) - const decryptedDataToBase64 = uint8ArrayToBase64(_decryptedData) - response = JSON.stringify(decryptedDataToBase64); - - break; - } catch (error) { - console.log({ error }) - const data = {}; - const errorMsg = error.message || "Error in decrypting data" - data['error'] = errorMsg; - response = JSON.stringify(data); - break - } - } - - case actions.DECRYPT_DATA_GROUP: { - const requiredFields = ['encryptedData']; - 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 { encryptedData: data64EncryptedData } = data - try { - const allCombined = base64ToUint8Array(data64EncryptedData); - const str = "qortalEncryptedData"; - const strEncoder = new TextEncoder(); - const strUint8Array = strEncoder.encode(str); - - // Extract the nonce - const nonceStartPosition = strUint8Array.length; - const nonceEndPosition = nonceStartPosition + 24; // Nonce is 24 bytes - const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition); - - // Extract the shared keyNonce - const keyNonceStartPosition = nonceEndPosition; - const keyNonceEndPosition = keyNonceStartPosition + 24; // Nonce is 24 bytes - const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition); - - // Calculate count first - const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes) - const countArray = allCombined.slice(countStartPosition, countStartPosition + 4); - const count = new Uint32Array(countArray.buffer)[0]; - - // Then use count to calculate encryptedData - const encryptedDataStartPosition = keyNonceEndPosition; // start position of encryptedData - const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4); - const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition); - - // Extract the encrypted keys - // 32+16 = 48 - const combinedKeys = allCombined.slice(encryptedDataEndPosition, encryptedDataEndPosition + (count * 48)); - const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey - const publicKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.publicKey - - if (!privateKey || !publicKey) { - data['error'] = "Unable to retrieve keys" - response = JSON.stringify(data); - break - } - - const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) - const convertedPublicKey = ed2curve.convertPublicKey(publicKey) - const sharedSecret = new Uint8Array(32) - nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) - for (let i = 0; i < count; i++) { - const encryptedKey = combinedKeys.slice(i * 48, (i + 1) * 48); - // Decrypt the symmetric key. - const decryptedKey = nacl.secretbox.open(encryptedKey, keyNonce, sharedSecret); - // If decryption was successful, decryptedKey will not be null. - if (decryptedKey) { - // Decrypt the data using the symmetric key. - const decryptedData = nacl.secretbox.open(encryptedData, nonce, decryptedKey); - - // If decryption was successful, decryptedData will not be null. - if (decryptedData) { - const decryptedDataToBase64 = uint8ArrayToBase64(decryptedData) - response = JSON.stringify(decryptedDataToBase64); - break; - } + data['error'] = errorMsg; + response = JSON.stringify(data); + break } + + + const decryptedDataToBase64 = decryptDeprecatedSingle(uint8Array, publicKey) + response = JSON.stringify(decryptedDataToBase64); + break; + + + } + const startsWithQortalGroupEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalGroupEncryptedData"); + + if (startsWithQortalGroupEncryptedData) { + + const decryptedData = decryptGroupData(encryptedData) + const decryptedDataToBase64 = uint8ArrayToBase64(decryptedData) + response = JSON.stringify(decryptedDataToBase64); + break; + } - if (!response) { - const data = {}; - data['error'] = "Unable to decrypt data"; - response = JSON.stringify(data); - } + const errorMsg = "Unable to decrypt" + data['error'] = errorMsg; + response = JSON.stringify(data); + break } catch (error) { console.log({ error }) const data = {}; const errorMsg = error.message || "Error in decrypting data" data['error'] = errorMsg; response = JSON.stringify(data); + break } - break; } case actions.GET_LIST_ITEMS: { From adc8ba42a0fed3b35d80ea16404e83e38d0d388f Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 13 May 2023 03:33:18 +0300 Subject: [PATCH 05/27] added to multiple --- plugins/plugins/core/qdn/browser/browser.src.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index f04aa31c..9889d87e 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -1007,9 +1007,9 @@ class WebBrowser extends LitElement { response = JSON.stringify(data); break } - if (data.encrypt && !data.recipientPublicKey) { + if (data.encrypt && (!data.publicKeys || (Array.isArray(data.publicKeys) && data.publicKeys.length === 0))) { let data = {}; - data['error'] = "Encrypting data requires the recipient's public key"; + data['error'] = "Encrypting data requires public keys"; response = JSON.stringify(data); break } @@ -1068,13 +1068,14 @@ class WebBrowser extends LitElement { throw new Error("Only encrypted data can go into private services") } + if (data.encrypt) { try { - const encryptDataResponse = encryptData({ - data64, recipientPublicKey: data.recipientPublicKey + const encryptDataResponse = encryptDataGroup({ + data64, publicKeys: data.publicKeys }) - if (encryptDataResponse.encryptedData) { - data64 = encryptDataResponse.encryptedData + if (encryptDataResponse) { + data64 = encryptDataResponse } } catch (error) { From cfe9a0c0a3987db54ac0b456cbbf7deeaa343053 Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 13 May 2023 03:39:18 +0300 Subject: [PATCH 06/27] added ui user public key --- plugins/plugins/core/components/qdn-action-encryption.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index 3a3adfb6..eeaa37f6 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -104,7 +104,12 @@ export const encryptData = ({ data64, recipientPublicKey }) => { } export const encryptDataGroup = ({ data64, publicKeys }) => { - const publicKeysDuplicateFree = [...new Set(publicKeys)]; + const userPublicKey = window.parent.Base58.decode(window.parent.reduxStore.getState().app.selectedAddress.keyPair.publicKey) + let combinedPublicKeys = publicKeys + if (userPublicKey) { + combinedPublicKeys = [...publicKeys, userPublicKey] + } + const publicKeysDuplicateFree = [...new Set(combinedPublicKeys)]; const Uint8ArrayData = base64ToUint8Array(data64) if (!(Uint8ArrayData instanceof Uint8Array)) { From 430413c572e1f820c7bb88332a73983d46de6647 Mon Sep 17 00:00:00 2001 From: Phillip Date: Thu, 25 May 2023 21:39:48 +0300 Subject: [PATCH 07/27] fix base58 publicKey --- plugins/plugins/core/components/qdn-action-encryption.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index eeaa37f6..cd990395 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -104,11 +104,12 @@ export const encryptData = ({ data64, recipientPublicKey }) => { } export const encryptDataGroup = ({ data64, publicKeys }) => { - const userPublicKey = window.parent.Base58.decode(window.parent.reduxStore.getState().app.selectedAddress.keyPair.publicKey) + const userPublicKey = window.parent.reduxStore.getState().app.selectedAddress.base58PublicKey let combinedPublicKeys = publicKeys if (userPublicKey) { combinedPublicKeys = [...publicKeys, userPublicKey] } + const publicKeysDuplicateFree = [...new Set(combinedPublicKeys)]; const Uint8ArrayData = base64ToUint8Array(data64) From 4ee98333141c302ddf37b0afb0c6133d9aaf5e3f Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 3 Jun 2023 18:22:16 +0300 Subject: [PATCH 08/27] added file option to encript --- .../plugins/core/components/qdn-action-encryption.js | 4 ++-- plugins/plugins/core/qdn/browser/browser.src.js | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index cd990395..a017d95e 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -157,7 +157,7 @@ export const encryptDataGroup = ({ data64, publicKeys }) => { encryptedKeys.push(encryptedKey); }); - const str = "qortalEncryptedData"; + const str = "qortalGroupEncryptedData"; const strEncoder = new TextEncoder(); const strUint8Array = strEncoder.encode(str); @@ -247,7 +247,7 @@ export function decryptDeprecatedSingle(uint8Array, publicKey) { export function decryptGroupData(data64EncryptedData) { const allCombined = base64ToUint8Array(data64EncryptedData); - const str = "qortalEncryptedData"; + const str = "qortalGroupEncryptedData"; const strEncoder = new TextEncoder(); const strUint8Array = strEncoder.encode(str); diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index 9889d87e..f0ebaed0 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -566,7 +566,6 @@ class WebBrowser extends LitElement { const { encryptedData, publicKey } = data - try { let data = {}; if (!encryptedData) { @@ -579,7 +578,6 @@ class WebBrowser extends LitElement { } const uint8Array = base64ToUint8Array(encryptedData) const startsWithQortalEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalEncryptedData"); - if (startsWithQortalEncryptedData) { if (!publicKey) { @@ -598,7 +596,6 @@ class WebBrowser extends LitElement { } const startsWithQortalGroupEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalGroupEncryptedData"); - if (startsWithQortalGroupEncryptedData) { const decryptedData = decryptGroupData(encryptedData) @@ -893,6 +890,9 @@ class WebBrowser extends LitElement { response = JSON.stringify(data); break } + if (data.file) { + data64 = await fileToBase64(data.file) + } if (data.encrypt) { try { @@ -1067,10 +1067,14 @@ class WebBrowser extends LitElement { if (!data.encrypt && service.endsWith("_PRIVATE")) { throw new Error("Only encrypted data can go into private services") } + if (data.file) { + data64 = await fileToBase64(data.file) + } if (data.encrypt) { try { + const encryptDataResponse = encryptDataGroup({ data64, publicKeys: data.publicKeys }) From 27843d8970e1c4ab1ab56d90ee8cd68f0a5164c7 Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 8 Jul 2023 02:24:39 +0300 Subject: [PATCH 09/27] fixed bug when open sender's encrypted data --- .../core/components/qdn-action-encryption.js | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/plugins/plugins/core/components/qdn-action-encryption.js b/plugins/plugins/core/components/qdn-action-encryption.js index a017d95e..b7b416f6 100644 --- a/plugins/plugins/core/components/qdn-action-encryption.js +++ b/plugins/plugins/core/components/qdn-action-encryption.js @@ -98,7 +98,6 @@ export const encryptData = ({ data64, recipientPublicKey }) => { recipientPublicKey } } catch (error) { - console.log({ error }) throw new Error("Error in encrypting data") } } @@ -156,14 +155,16 @@ export const encryptDataGroup = ({ data64, publicKeys }) => { encryptedKeys.push(encryptedKey); }); - const str = "qortalGroupEncryptedData"; const strEncoder = new TextEncoder(); const strUint8Array = strEncoder.encode(str); + // Convert sender's public key to Uint8Array and add to the message + const senderPublicKeyUint8Array = window.parent.Base58.decode(userPublicKey); + // Combine all data into a single Uint8Array. // Calculate size of combinedData - let combinedDataSize = strUint8Array.length + nonce.length + keyNonce.length + encryptedData.length + 4; + let combinedDataSize = strUint8Array.length + nonce.length + keyNonce.length + senderPublicKeyUint8Array.length + encryptedData.length + 4; let encryptedKeysSize = 0; encryptedKeys.forEach((key) => { @@ -177,10 +178,11 @@ export const encryptDataGroup = ({ data64, publicKeys }) => { combinedData.set(strUint8Array); combinedData.set(nonce, strUint8Array.length); combinedData.set(keyNonce, strUint8Array.length + nonce.length); - combinedData.set(encryptedData, strUint8Array.length + nonce.length + keyNonce.length); + combinedData.set(senderPublicKeyUint8Array, strUint8Array.length + nonce.length + keyNonce.length); + combinedData.set(encryptedData, strUint8Array.length + nonce.length + keyNonce.length + senderPublicKeyUint8Array.length); // Initialize offset for encryptedKeys - let encryptedKeysOffset = strUint8Array.length + nonce.length + encryptedData.length + keyNonce.length; + let encryptedKeysOffset = strUint8Array.length + nonce.length + keyNonce.length + senderPublicKeyUint8Array.length + encryptedData.length; encryptedKeys.forEach((key) => { combinedData.set(key, encryptedKeysOffset); encryptedKeysOffset += key.length; @@ -261,13 +263,18 @@ export function decryptGroupData(data64EncryptedData) { const keyNonceEndPosition = keyNonceStartPosition + 24; // Nonce is 24 bytes const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition); + // Extract the sender's public key + const senderPublicKeyStartPosition = keyNonceEndPosition; + const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32; // Public keys are 32 bytes + const senderPublicKey = allCombined.slice(senderPublicKeyStartPosition, senderPublicKeyEndPosition); + // Calculate count first const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes) const countArray = allCombined.slice(countStartPosition, countStartPosition + 4); const count = new Uint32Array(countArray.buffer)[0]; // Then use count to calculate encryptedData - const encryptedDataStartPosition = keyNonceEndPosition; // start position of encryptedData + const encryptedDataStartPosition = senderPublicKeyEndPosition; // start position of encryptedData const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4); const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition); @@ -275,20 +282,21 @@ export function decryptGroupData(data64EncryptedData) { // 32+16 = 48 const combinedKeys = allCombined.slice(encryptedDataEndPosition, encryptedDataEndPosition + (count * 48)); const privateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey - const publicKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.publicKey - if (!privateKey || !publicKey) { + if (!privateKey) { throw new Error("Unable to retrieve keys") } const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) - const convertedPublicKey = ed2curve.convertPublicKey(publicKey) + const convertedSenderPublicKey = ed2curve.convertPublicKey(senderPublicKey) const sharedSecret = new Uint8Array(32) - nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) + nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedSenderPublicKey) for (let i = 0; i < count; i++) { const encryptedKey = combinedKeys.slice(i * 48, (i + 1) * 48); + // Decrypt the symmetric key. const decryptedKey = nacl.secretbox.open(encryptedKey, keyNonce, sharedSecret); + // If decryption was successful, decryptedKey will not be null. if (decryptedKey) { // Decrypt the data using the symmetric key. @@ -296,15 +304,11 @@ export function decryptGroupData(data64EncryptedData) { // If decryption was successful, decryptedData will not be null. if (decryptedData) { - console.log({ decryptedData }) - return decryptedData + return decryptedData } } } - if (!response) { - throw new Erorr("Unable to decrypt data") - - } -} \ No newline at end of file + throw new Error("Unable to decrypt data") +} From 3b26e82d420eaf5f8f202534774d0e680d7120ed Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sun, 23 Jul 2023 17:38:04 +0200 Subject: [PATCH 10/27] Update npm and niodejs --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3d9c3ddc..ee11d8c0 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Easiest way to install the lastest required packages on Linux is via nvm. ``` source ~/.profile ``` (For Debian based distro)
``` source ~/.bashrc ``` (For Fedora / CentOS)
``` nvm ls-remote ``` (Fetch list of available versions)
-``` nvm install v18.14.0 ``` (LTS: Hydrogen supported by Electron)
-``` npm --location=global install npm@9.7.2 ```
+``` nvm install v18.15.0 ``` (LTS: Hydrogen supported by Electron)
+``` npm --location=global install npm@9.8.1 ```
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method. From 38c4c7baa29524b95069b93bf5c75089929b9033 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:01:30 +0200 Subject: [PATCH 11/27] Add clear cache --- electron.js | 31 +++++++++++++++++++------------ lib/preload.js | 1 + 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/electron.js b/electron.js index ffbc9538..7190f5c3 100644 --- a/electron.js +++ b/electron.js @@ -1,16 +1,17 @@ const { - app, - BrowserWindow, - ipcMain, - ipcRenderer, - Menu, - Notification, - Tray, - nativeImage, - dialog, - webContents, - nativeTheme, - crashReporter + app, + BrowserWindow, + ipcMain, + ipcRenderer, + Menu, + Notification, + Tray, + nativeImage, + dialog, + webContents, + nativeTheme, + crashReporter, + webFrame } = require('electron') const { autoUpdater } = require('electron-updater') @@ -1031,6 +1032,12 @@ if (!isLock) { } }) }) + ipcMain.on('clear-all-cache', (event) => { + const theWindows = BrowserWindow.getAllWindows()[0] + const ses = theWindows.webContents.session + console.clear() + ses.clearCache() + }) ipcMain.on('check-for-update', (event) => { const check = new Notification({ title: i18n.__("electron_translate_43"), diff --git a/lib/preload.js b/lib/preload.js index fed27281..7f3a0cf8 100644 --- a/lib/preload.js +++ b/lib/preload.js @@ -5,4 +5,5 @@ contextBridge.exposeInMainWorld('electronAPI', { checkForUpdate: () => ipcRenderer.send('check-for-update'), showMyMenu: () => ipcRenderer.send('show-my-menu'), focusApp: () => ipcRenderer.send('focus-app'), + clearMyCache: () => ipcRenderer.send('clear-all-cache'), }) \ No newline at end of file From 1757030eb3729decb59df3c91ed255f7af622c3b Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:13:39 +0200 Subject: [PATCH 12/27] Update dependencies and node --- package-lock.json | 697 +++++++++++++++++++++++++--------------------- package.json | 42 +-- 2 files changed, 408 insertions(+), 331 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72c2c6c2..39d0c956 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,14 +12,14 @@ "@hapi/hapi": "21.3.2", "@hapi/inert": "7.1.0", "@lit-labs/motion": "1.0.3", - "@tiptap/core": "2.0.3", - "@tiptap/extension-highlight": "2.0.3", - "@tiptap/extension-image": "2.0.3", - "@tiptap/extension-placeholder": "2.0.3", - "@tiptap/extension-underline": "2.0.3", - "@tiptap/html": "2.0.3", - "@tiptap/pm": "2.0.3", - "@tiptap/starter-kit": "2.0.3", + "@tiptap/core": "2.0.4", + "@tiptap/extension-highlight": "2.0.4", + "@tiptap/extension-image": "2.0.4", + "@tiptap/extension-placeholder": "2.0.4", + "@tiptap/extension-underline": "2.0.4", + "@tiptap/html": "2.0.4", + "@tiptap/pm": "2.0.4", + "@tiptap/starter-kit": "2.0.4", "asmcrypto.js": "2.3.2", "bcryptjs": "2.4.3", "buffer": "6.0.3", @@ -41,12 +41,12 @@ "prosemirror-gapcursor": "1.3.2", "prosemirror-history": "1.3.2", "prosemirror-keymap": "1.2.2", - "prosemirror-model": "1.19.2", + "prosemirror-model": "1.19.3", "prosemirror-schema-list": "1.3.0", "prosemirror-state": "1.4.3", "prosemirror-transform": "1.7.3", - "prosemirror-view": "1.31.5", - "sass": "1.63.6", + "prosemirror-view": "1.31.6", + "sass": "1.64.1", "short-unique-id": "4.4.4" }, "devDependencies": { @@ -89,19 +89,19 @@ "@qortal/rollup-plugin-web-worker-loader": "1.6.4", "@rollup/plugin-alias": "5.0.0", "@rollup/plugin-babel": "6.0.3", - "@rollup/plugin-commonjs": "25.0.2", + "@rollup/plugin-commonjs": "25.0.3", "@rollup/plugin-node-resolve": "15.1.0", "@rollup/plugin-replace": "5.0.2", "@rollup/plugin-terser": "0.4.3", - "@vaadin/avatar": "24.1.3", - "@vaadin/button": "24.1.3", - "@vaadin/grid": "24.1.3", - "@vaadin/icons": "24.1.3", - "@vaadin/password-field": "24.1.3", - "@vaadin/tooltip": "24.1.3", + "@vaadin/avatar": "24.1.4", + "@vaadin/button": "24.1.4", + "@vaadin/grid": "24.1.4", + "@vaadin/icons": "24.1.4", + "@vaadin/password-field": "24.1.4", + "@vaadin/tooltip": "24.1.4", "@zip.js/zip.js": "2.7.20", "axios": "1.4.0", - "electron": "25.3.0", + "electron": "25.3.1", "electron-builder": "24.4.0", "electron-packager": "17.1.1", "epml": "0.3.3", @@ -115,14 +115,14 @@ "pwa-helpers": "0.9.1", "redux": "4.2.1", "redux-thunk": "2.4.2", - "rollup": "3.26.2", + "rollup": "3.26.3", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-progress": "1.1.2", "rollup-plugin-scss": "3.0.0", "shelljs": "0.8.5" }, "engines": { - "node": ">=18.14.0" + "node": ">=18.15.0" } }, "node_modules/@ampproject/remapping": { @@ -1002,9 +1002,9 @@ } }, "node_modules/@hapi/accept": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-6.0.1.tgz", - "integrity": "sha512-aLkYj7zzgC3CSlEVOs84eBOEE3i9xZK2tdQEP+TOj2OFzMWCi9zjkRet82V3GGjecE//zFrCLKIykuaE0uM4bg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-6.0.2.tgz", + "integrity": "sha512-xaTLf29Zeph/B32hekmgxLFsEPuX1xQYyZu0gJ4ZCHKU6nXmBRXfBymtWNEK0souOJcX2XHWUaZU6JzccuuMpg==", "dependencies": { "@hapi/boom": "^10.0.1", "@hapi/hoek": "^11.0.2" @@ -1477,9 +1477,9 @@ } }, "node_modules/@linaria/logger": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@linaria/logger/-/logger-4.0.0.tgz", - "integrity": "sha512-YnBq0JlDWMEkTOK+tMo5yEVR0f5V//6qMLToGcLhTyM9g9i+IDFn51Z+5q2hLk7RdG4NBPgbcCXYi2w4RKsPeg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@linaria/logger/-/logger-4.5.0.tgz", + "integrity": "sha512-XdQLk242Cpcsc9a3Cz1ktOE5ysTo2TpxdeFQEPwMm8Z/+F/S6ZxBDdHYJL09srXWz3hkJr3oS2FPuMZNH1HIxw==", "dependencies": { "debug": "^4.1.1", "picocolors": "^1.0.0" @@ -1489,22 +1489,22 @@ } }, "node_modules/@linaria/tags": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@linaria/tags/-/tags-4.3.5.tgz", - "integrity": "sha512-PgaIi8Vv89YOjc6rpKL/uPg2w4k0rAwAYxcqeXqzKqsEAste5rgB8xp1/KUOG0oAOkPd3MRL6Duj+m0ZwJ3g+g==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@linaria/tags/-/tags-4.5.2.tgz", + "integrity": "sha512-ougIJrket1Q1qBc/JlBBt63dzFZwrDxx51MsVeYQ0lagbfLLHCfdVKFrsQy2YBQkBFw5hAHDP9+0uPvBy662ng==", "dependencies": { "@babel/generator": "^7.20.4", - "@linaria/logger": "^4.0.0", - "@linaria/utils": "^4.3.4" + "@linaria/logger": "^4.5.0", + "@linaria/utils": "^4.5.1" }, "engines": { "node": "^12.16.0 || >=13.7.0" } }, "node_modules/@linaria/utils": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@linaria/utils/-/utils-4.3.4.tgz", - "integrity": "sha512-vt6WJG54n+KANaqxOfzIIU7aSfFHEWFbnGLsgxL7nASHqO0zezrNA2y2Rrp80zSeTW+wSpbmDM4uJyC9UW1qoA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@linaria/utils/-/utils-4.5.1.tgz", + "integrity": "sha512-BvVEDuwltfsia3tT72EFoqQvlkockii4rRdexBV5QOxmxVLFPo2jp+cqIybpa8aBtSpiflCdgwYvz+YlLR5ZCg==", "dependencies": { "@babel/core": "^7.20.2", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", @@ -1512,13 +1512,79 @@ "@babel/plugin-transform-modules-commonjs": "^7.19.6", "@babel/traverse": "^7.20.1", "@babel/types": "^7.20.2", - "@linaria/logger": "^4.0.0", - "babel-merge": "^3.0.0" + "@linaria/logger": "^4.5.0", + "babel-merge": "^3.0.0", + "find-up": "^5.0.0" }, "engines": { "node": "^12.16.0 || >=13.7.0" } }, + "node_modules/@linaria/utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@linaria/utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@linaria/utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@linaria/utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@linaria/utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, "node_modules/@lit-labs/motion": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@lit-labs/motion/-/motion-1.0.3.tgz", @@ -3123,9 +3189,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.2.tgz", - "integrity": "sha512-NGTwaJxIO0klMs+WSFFtBP7b9TdTJ3K76HZkewT8/+yHzMiUGVQgaPtLQxNVYIgT5F7lxkEyVID+yS3K7bhCow==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.3.tgz", + "integrity": "sha512-uBdtWr/H3BVcgm97MUdq2oJmqBR23ny1hOrWe2PKo9FTbjsGqg32jfasJUKYAI5ouqacjRnj65mBB/S79F+GQA==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -3262,9 +3328,9 @@ } }, "node_modules/@tiptap/core": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.0.3.tgz", - "integrity": "sha512-jLyVIWAdjjlNzrsRhSE2lVL/7N8228/1R1QtaVU85UlMIwHFAcdzhD8FeiKkqxpTnGpaDVaTy7VNEtEgaYdCyA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.0.4.tgz", + "integrity": "sha512-2YOMjRqoBGEP4YGgYpuPuBBJHMeqKOhLnS0WVwjVP84zOmMgZ7A8M6ILC9Xr7Q/qHZCvyBGWOSsI7+3HsEzzYQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3274,9 +3340,9 @@ } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.0.3.tgz", - "integrity": "sha512-rkUcFv2iL6f86DBBHoa4XdKNG2StvkJ7tfY9GoMpT46k3nxOaMTqak9/qZOo79TWxMLYtXzoxtKIkmWsbbcj4A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.0.4.tgz", + "integrity": "sha512-z5qfuLi04OgCBI6/odzB2vhulT/wpjymYOnON65vLXGZZbUw4cbPloykhqgWvQp+LzKH+HBhl4fz53d5CgnbOA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3286,9 +3352,9 @@ } }, "node_modules/@tiptap/extension-bold": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.0.3.tgz", - "integrity": "sha512-OGT62fMRovSSayjehumygFWTg2Qn0IDbqyMpigg/RUAsnoOI2yBZFVrdM2gk1StyoSay7gTn2MLw97IUfr7FXg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.0.4.tgz", + "integrity": "sha512-CWSQy1uWkVsen8HUsqhm+oEIxJrCiCENABUbhaVcJL/MqhnP4Trrh1B6O00Yfoc0XToPRRibDaHMFs4A3MSO0g==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3298,9 +3364,9 @@ } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.3.tgz", - "integrity": "sha512-RtaLiRvZbMTOje+FW5bn+mYogiIgNxOm065wmyLPypnTbLSeHeYkoqVSqzZeqUn+7GLnwgn1shirUe6csVE/BA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.4.tgz", + "integrity": "sha512-JSZKBVTaKSuLl5fR4EKE4dOINOrgeRHYA25Vj6cWjgdvpTw5ef7vcUdn9yP4JwTmLRI+VnnMlYL3rqigU3iZNg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3310,9 +3376,9 @@ } }, "node_modules/@tiptap/extension-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.0.3.tgz", - "integrity": "sha512-LsVCKVxgBtkstAr1FjxN8T3OjlC76a2X8ouoZpELMp+aXbjqyanCKzt+sjjUhE4H0yLFd4v+5v6UFoCv4EILiw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.0.4.tgz", + "integrity": "sha512-HuwJSJkipZf4hkns9witv1CABNIPiB9C8lgAQXK4xJKcoUQChcnljEL+PQ2NqeEeMTEeV3nG3A/0QafH0pgTgg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3322,9 +3388,9 @@ } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.0.3.tgz", - "integrity": "sha512-F4xMy18EwgpyY9f5Te7UuF7UwxRLptOtCq1p2c2DfxBvHDWhAjQqVqcW/sq/I/WuED7FwCnPLyyAasPiVPkLPw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.0.4.tgz", + "integrity": "sha512-In2tV3rgm/MznVF0N7qYsYugPWSzhZHaCRCWcFKNvllMExpo91bUWvk+hXaIhhPxvuqGIVezjybwrYuU3bJW0g==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3335,9 +3401,9 @@ } }, "node_modules/@tiptap/extension-document": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.0.3.tgz", - "integrity": "sha512-PsYeNQQBYIU9ayz1R11Kv/kKNPFNIV8tApJ9pxelXjzcAhkjncNUazPN/dyho60mzo+WpsmS3ceTj/gK3bCtWA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.0.4.tgz", + "integrity": "sha512-mCj2fAhnNhIHttPSqfTPSSTGwClGaPYvhT56Ij/Pi4iCrWjPXzC4XnIkIHSS34qS2tJN4XJzr/z7lm3NeLkF1w==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3347,9 +3413,9 @@ } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.3.tgz", - "integrity": "sha512-McthMrfusn6PjcaynJLheZJcXto8TaIW5iVitYh8qQrDXr31MALC/5GvWuiswmQ8bAXiWPwlLDYE/OJfwtggaw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.4.tgz", + "integrity": "sha512-1OmKBv/E+nJo2vsosvu8KwFiBB+gZM1pY61qc7JbwEKHSYAxUFHfvLkIA0IQ53Z0DHMrFSKgWmHEcbnqtGevCA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3360,9 +3426,9 @@ } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.3.tgz", - "integrity": "sha512-6I9EzzsYOyyqDvDvxIK6Rv3EXB+fHKFj8ntHO8IXmeNJ6pkhOinuXVsW6Yo7TcDYoTj4D5I2MNFAW2rIkgassw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.4.tgz", + "integrity": "sha512-VxmKfBQjSSu1mNvHlydA4dJW/zawGKyqmnryiFNcUV9s+/HWLR5i9SiUl4wJM/B8sG8cQxClne5/LrCAeGNYuA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3373,9 +3439,9 @@ } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.0.3.tgz", - "integrity": "sha512-RCln6ARn16jvKTjhkcAD5KzYXYS0xRMc0/LrHeV8TKdCd4Yd0YYHe0PU4F9gAgAfPQn7Dgt4uTVJLN11ICl8sQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.0.4.tgz", + "integrity": "sha512-4j8BZa6diuoRytWoIc7j25EYWWut5TZDLbb+OVURdkHnsF8B8zeNTo55W40CdwSaSyTtXtxbTIldV80ShQarGQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3385,9 +3451,9 @@ } }, "node_modules/@tiptap/extension-heading": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.0.3.tgz", - "integrity": "sha512-f0IEv5ms6aCzL80WeZ1qLCXTkRVwbpRr1qAETjg3gG4eoJN18+lZNOJYpyZy3P92C5KwF2T3Av00eFyVLIbb8Q==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.0.4.tgz", + "integrity": "sha512-EfitUbew5ljH3xVlBXAxqqcJ4rjv15b8379LYOV6KQCf+Y1wY0gy9Q8wXSnrsAagqrvqipja4Ihn3OZeyIM+CA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3397,9 +3463,9 @@ } }, "node_modules/@tiptap/extension-highlight": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.0.3.tgz", - "integrity": "sha512-NrtibY8cZkIjZMQuHRrKd4php+plOvAoSo8g3uVFu275I/Ixt5HqJ53R4voCXs8W8BOBRs2HS2QX8Cjh79XhtA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.0.4.tgz", + "integrity": "sha512-z1hcpf0eHHdaBE0pewXiNIu+QBodw4IAbZykTXMaY1xCsbYWfOJxeIb5o+CEG5HBsmaoJrCYenQw71xzgV0hKA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3409,9 +3475,9 @@ } }, "node_modules/@tiptap/extension-history": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.0.3.tgz", - "integrity": "sha512-00KHIcJ8kivn2ARI6NQYphv2LfllVCXViHGm0EhzDW6NQxCrriJKE3tKDcTFCu7LlC5doMpq9Z6KXdljc4oVeQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.0.4.tgz", + "integrity": "sha512-3GAUszn1xZx3vniHMiX9BSKmfvb5QOb0oSLXInN+hx80CgJDIHqIFuhx2dyV9I/HWpa0cTxaLWj64kfDzb1JVg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3422,9 +3488,9 @@ } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.3.tgz", - "integrity": "sha512-SZRUSh07b/M0kJHNKnfBwBMWrZBEm/E2LrK1NbluwT3DBhE+gvwiEdBxgB32zKHNxaDEXUJwUIPNC3JSbKvPUA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.4.tgz", + "integrity": "sha512-OMx2ImQseKbSUjPbbRCuYGOJshxYedh9giWAqwgWWokhYkH4nGxXn5m7+Laj+1wLre4bnWgHWVY4wMGniEj3aw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3435,9 +3501,9 @@ } }, "node_modules/@tiptap/extension-image": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.0.3.tgz", - "integrity": "sha512-hS9ZJwz0md07EHsC+o4NuuJkhCZsZn7TuRz/2CvRSj2fWFIz+40CyNAHf/2J0qNugG9ommXaemetsADeEZP9ag==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.0.4.tgz", + "integrity": "sha512-5iQ96pt9xppM8sWzwhGgc99PPoYPQuokTaCXAQKDI0Y1CFCjZ+/duUG3al1VUMpBXsjJw3/RVO1+7CEhRTd3mA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3447,9 +3513,9 @@ } }, "node_modules/@tiptap/extension-italic": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.0.3.tgz", - "integrity": "sha512-cfS5sW0gu7qf4ihwnLtW/QMTBrBEXaT0sJl3RwkhjIBg/65ywJKE5Nz9ewnQHmDeT18hvMJJ1VIb4j4ze9jj9A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.0.4.tgz", + "integrity": "sha512-C/6+qs4Jh8xERRP0wcOopA1+emK8MOkBE4RQx5NbPnT2iCpERP0GlmHBFQIjaYPctZgKFHxsCfRnneS5Xe76+A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3459,9 +3525,9 @@ } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.0.3.tgz", - "integrity": "sha512-p7cUsk0LpM1PfdAuFE8wYBNJ3gvA0UhNGR08Lo++rt9UaCeFLSN1SXRxg97c0oa5+Ski7SrCjIJ5Ynhz0viTjQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.0.4.tgz", + "integrity": "sha512-tSkbLgRo1QMNDJttWs9FeRywkuy5T2HdLKKfUcUNzT3s0q5AqIJl7VyimsBL4A6MUfN1qQMZCMHB4pM9Mkluww==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3471,9 +3537,9 @@ } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.3.tgz", - "integrity": "sha512-ZB3MpZh/GEy1zKgw7XDQF4FIwycZWNof1k9WbDZOI063Ch4qHZowhVttH2mTCELuyvTMM/o9a8CS7qMqQB48bw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.4.tgz", + "integrity": "sha512-Kfg+8k9p4iJCUKP/yIa18LfUpl9trURSMP/HX3/yQTz9Ul1vDrjxeFjSE5uWNvupcXRAM24js+aYrCmV7zpU+Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3483,9 +3549,9 @@ } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.0.3.tgz", - "integrity": "sha512-a+tKtmj4bU3GVCH1NE8VHWnhVexxX5boTVxsHIr4yGG3UoKo1c5AO7YMaeX2W5xB5iIA+BQqOPCDPEAx34dd2A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.0.4.tgz", + "integrity": "sha512-nDxpopi9WigVqpfi8nU3B0fWYB14EMvKIkutNZo8wJvKGTZufNI8hw66wupIx/jZH1gFxEa5dHerw6aSYuWjgQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3495,9 +3561,9 @@ } }, "node_modules/@tiptap/extension-placeholder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.0.3.tgz", - "integrity": "sha512-Z42jo0termRAf0S0L8oxrts94IWX5waU4isS2CUw8xCUigYyCFslkhQXkWATO1qRbjNFLKN2C9qvCgGf4UeBrw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.0.4.tgz", + "integrity": "sha512-Y8hjUYBGTbytgrsplSZdHGciqbuVHQX+h0JcuvVaIlAy1kR7hmbxJLqL8tNa7qLtTqo2MfS2942OtSv85JOCzA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3508,9 +3574,9 @@ } }, "node_modules/@tiptap/extension-strike": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.3.tgz", - "integrity": "sha512-RO4/EYe2iPD6ifDHORT8fF6O9tfdtnzxLGwZIKZXnEgtweH+MgoqevEzXYdS+54Wraq4TUQGNcsYhe49pv7Rlw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.4.tgz", + "integrity": "sha512-Men7LK6N/Dh3/G4/z2Z9WkDHM2Gxx1XyxYix2ZMf5CnqY37SeDNUnGDqit65pdIN3Y/TQnOZTkKSBilSAtXfJA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3520,9 +3586,9 @@ } }, "node_modules/@tiptap/extension-text": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.0.3.tgz", - "integrity": "sha512-LvzChcTCcPSMNLUjZe/A9SHXWGDHtvk73fR7CBqAeNU0MxhBPEBI03GFQ6RzW3xX0CmDmjpZoDxFMB+hDEtW1A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.0.4.tgz", + "integrity": "sha512-i8/VFlVZh7TkAI49KKX5JmC0tM8RGwyg5zUpozxYbLdCOv07AkJt+E1fLJty9mqH4Y5HJMNnyNxsuZ9Ol/ySRA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3532,9 +3598,9 @@ } }, "node_modules/@tiptap/extension-underline": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.0.3.tgz", - "integrity": "sha512-oMYa7qib/5wJjpUp79GZEe+E/iyf1oZBsgiG26IspEtVTHZmpn3+Ktud7l43y/hpTeEzFTKOF1/uVbayHtSERg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.0.4.tgz", + "integrity": "sha512-Hvhy3iV5dWs0SFTww6sIzyQSSgVzcQuiozhDs11iP+gvFjK7ejg86KZ8wAVvyCi9K3bOMhohsw1Q2b8JSnIxcg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3544,9 +3610,9 @@ } }, "node_modules/@tiptap/html": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/html/-/html-2.0.3.tgz", - "integrity": "sha512-F0mihUTJ+mqqczHl7du9kBmani3pkwYeEuc/xls+DlYobdTzhSqIaF/ce8utHwRxTvDUPwSEM7+ITr93e2PqQA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/html/-/html-2.0.4.tgz", + "integrity": "sha512-FEK220mIeH2dBSSMakM+LOPxG98ZuPT3GEvgEvywjIOO83selby3phmWTi2sC9MYD95RKtEMPMdSPUHCpGZaPw==", "dependencies": { "zeed-dom": "^0.9.19" }, @@ -3560,9 +3626,9 @@ } }, "node_modules/@tiptap/pm": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.0.3.tgz", - "integrity": "sha512-I9dsInD89Agdm1QjFRO9dmJtU1ldVSILNPW0pEhv9wYqYVvl4HUj/JMtYNqu2jWrCHNXQcaX/WkdSdvGJtmg5g==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.0.4.tgz", + "integrity": "sha512-DNgxntpEaiW7ciW0BTNTL0TFqAreZTrAROWakI4XaYRAyi5H9NfZW8jmwGwMBkoZ1KB3pfy+jT/Bisy4okEQGQ==", "dependencies": { "prosemirror-changeset": "^2.2.0", "prosemirror-collab": "^1.3.0", @@ -3592,29 +3658,29 @@ } }, "node_modules/@tiptap/starter-kit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.0.3.tgz", - "integrity": "sha512-t4WG4w93zTpL2VxhVyJJvl3kdLF001ZrhpOuEiZqEMBMUMbM56Uiigv1CnUQpTFrjDAh3IM8hkqzAh20TYw2iQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.0.4.tgz", + "integrity": "sha512-9WtVXhujyp5cOlE7qlcQMFr0FEx3Cvo1isvfQGzhKKPzXa3rR7FT8bnOFsten31/Ia/uwvGXAvRDQy24YfHdNA==", "dependencies": { - "@tiptap/core": "^2.0.3", - "@tiptap/extension-blockquote": "^2.0.3", - "@tiptap/extension-bold": "^2.0.3", - "@tiptap/extension-bullet-list": "^2.0.3", - "@tiptap/extension-code": "^2.0.3", - "@tiptap/extension-code-block": "^2.0.3", - "@tiptap/extension-document": "^2.0.3", - "@tiptap/extension-dropcursor": "^2.0.3", - "@tiptap/extension-gapcursor": "^2.0.3", - "@tiptap/extension-hard-break": "^2.0.3", - "@tiptap/extension-heading": "^2.0.3", - "@tiptap/extension-history": "^2.0.3", - "@tiptap/extension-horizontal-rule": "^2.0.3", - "@tiptap/extension-italic": "^2.0.3", - "@tiptap/extension-list-item": "^2.0.3", - "@tiptap/extension-ordered-list": "^2.0.3", - "@tiptap/extension-paragraph": "^2.0.3", - "@tiptap/extension-strike": "^2.0.3", - "@tiptap/extension-text": "^2.0.3" + "@tiptap/core": "^2.0.4", + "@tiptap/extension-blockquote": "^2.0.4", + "@tiptap/extension-bold": "^2.0.4", + "@tiptap/extension-bullet-list": "^2.0.4", + "@tiptap/extension-code": "^2.0.4", + "@tiptap/extension-code-block": "^2.0.4", + "@tiptap/extension-document": "^2.0.4", + "@tiptap/extension-dropcursor": "^2.0.4", + "@tiptap/extension-gapcursor": "^2.0.4", + "@tiptap/extension-hard-break": "^2.0.4", + "@tiptap/extension-heading": "^2.0.4", + "@tiptap/extension-history": "^2.0.4", + "@tiptap/extension-horizontal-rule": "^2.0.4", + "@tiptap/extension-italic": "^2.0.4", + "@tiptap/extension-list-item": "^2.0.4", + "@tiptap/extension-ordered-list": "^2.0.4", + "@tiptap/extension-paragraph": "^2.0.4", + "@tiptap/extension-strike": "^2.0.4", + "@tiptap/extension-text": "^2.0.4" }, "funding": { "type": "github", @@ -3688,9 +3754,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.16.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.19.tgz", - "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "version": "18.17.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.0.tgz", + "integrity": "sha512-GXZxEtOxYGFchyUzxvKI14iff9KZ2DI+A6a37o6EQevtg6uO9t+aUZKcaC1Te5Ng1OnLM7K9NVVj+FbecD9cJg==", "devOptional": true }, "node_modules/@types/object.omit": { @@ -3756,72 +3822,72 @@ } }, "node_modules/@vaadin/a11y-base": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/a11y-base/-/a11y-base-24.1.3.tgz", - "integrity": "sha512-Y3jkgYAFcpnWJ2cuZooolgNzVQkfHtGrYxVBi70HrsQuRNLHyHuAmapcvVaMYKsn9IQfJ9o3G85l4k9k/sbR3g==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/a11y-base/-/a11y-base-24.1.4.tgz", + "integrity": "sha512-NIPYbSUBLTL+X8A6Frqfv7OJk5As8k0/Ntw8GZ6w+e+pSLk/Yx5VVi1VxVNJGxZT40Y0wMkqsf2vveHKYRN58Q==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.1.3", + "@vaadin/component-base": "~24.1.4", "lit": "^2.0.0" } }, "node_modules/@vaadin/avatar": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/avatar/-/avatar-24.1.3.tgz", - "integrity": "sha512-tJkTst3LFZ5dOQy/+DEiUOqFOmv4sm8347WD0CuFJ0eXv+shBGHrVNpCLtOkniVpyNjNVhn4heJevvKOLoIcqQ==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/avatar/-/avatar-24.1.4.tgz", + "integrity": "sha512-9jT7mkmLk1no0jXXcJTJ0Jx35sxCAtn/7+j7nyEhyDkd7n5Zps3PyS5T9ywehly3QEcSODsDOA9Ag2PCIHLnWA==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/item": "~24.1.3", - "@vaadin/list-box": "~24.1.3", - "@vaadin/overlay": "~24.1.3", - "@vaadin/tooltip": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/item": "~24.1.4", + "@vaadin/list-box": "~24.1.4", + "@vaadin/overlay": "~24.1.4", + "@vaadin/tooltip": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/button": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/button/-/button-24.1.3.tgz", - "integrity": "sha512-9DlXWJsLn3oPuBzTj9d0QyjmIwYabOkPvaF5d6JmfhSoC8lPVAEPEwczFfCaLuYumAyutqOIYIvBqZATanB+mA==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/button/-/button-24.1.4.tgz", + "integrity": "sha512-fb/ybHCr7ogYnxXqYpy/7q0XssSufAKiuGYfyh2wqyp19nysB2bm1auSh8wGFQDfPZvHSlg4ssDcY+WkxKJs8Q==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3", + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4", "lit": "^2.0.0" } }, "node_modules/@vaadin/checkbox": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/checkbox/-/checkbox-24.1.3.tgz", - "integrity": "sha512-BRiSv8bKthBn67+imdqa23xPFTgj6nzQ9DcPkVba/1DHbV5f5CC6pPQwfcEfvW/rDRjBK4BLIKakzj8F94utIg==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/checkbox/-/checkbox-24.1.4.tgz", + "integrity": "sha512-Wa791NTQdM+OSkGz3Z2co9VUvl3dWeQ4idYIAiN8gWNFZtUBRp9XRhZHzTzGSNFP+IofFRqThZIIEyNhHXmUwA==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/field-base": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3", + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/field-base": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4", "lit": "^2.0.0" } }, "node_modules/@vaadin/component-base": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/component-base/-/component-base-24.1.3.tgz", - "integrity": "sha512-IIfbc6BYxuqkuQ8P/oIqpoIDL87rkI3oCAGj3H8bUt9F1Z6cOjypDoZhn/qpNj5sffQc+QlQAYjH9THUyzFTZA==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/component-base/-/component-base-24.1.4.tgz", + "integrity": "sha512-KjE+hemOwG278lOL7lK97JgNZ/3bdLYU2CHvsrWxltYqRiQP1K+X6qpuX6aeNo83mZ2mbLSKE4kvrlheWOC8jQ==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", @@ -3832,173 +3898,173 @@ } }, "node_modules/@vaadin/field-base": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/field-base/-/field-base-24.1.3.tgz", - "integrity": "sha512-cOuOITOCAXwxW6qwdoPoiACIv6QBk1qIs3L2FAxjvxabKqSl+aP32TqgYTp5zjmTNgMylgrMG+9fhAyfmi9Pcw==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/field-base/-/field-base-24.1.4.tgz", + "integrity": "sha512-zqAR2gngUw/oU/7zifRdVgzHEpq8FYUuwTo8AGUFekGGKi1MyaPJMVnykFcokepIzdPv50EBskqXCpRFSwY6jA==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", "lit": "^2.0.0" } }, "node_modules/@vaadin/grid": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/grid/-/grid-24.1.3.tgz", - "integrity": "sha512-tGt7MqtRGQlB/ZCWfA385SGr224HgHlERNxW5L3k4qWuJj4LNWveGwizjMEKga/x+FVBRbqKh0VDVb+4hbHWJg==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/grid/-/grid-24.1.4.tgz", + "integrity": "sha512-8wqXIWohsI/iRg5x3UAm6xLh+nXbHAtixlIJ0lvmGxu8v+H6b3gtZcIqKSv5pfQsgC/T6gmorpnW0ZjyFk4kww==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/checkbox": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/lit-renderer": "~24.1.3", - "@vaadin/text-field": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/checkbox": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/lit-renderer": "~24.1.4", + "@vaadin/text-field": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/icon": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/icon/-/icon-24.1.3.tgz", - "integrity": "sha512-qMs6wUJu5Nh+H/zdbRuEyHkIp/x8GNGdbxXdM9yBvFcZEkxLF5zWVHLHjTj15aNJB/vzVTANf9AS8siKlRV+3A==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/icon/-/icon-24.1.4.tgz", + "integrity": "sha512-+cW2HgZj00sXxZvcPv7qZX7S4HeQS+fBnRyTOrwOGBNKC7OuT8Xk+UyN3zCwYDteEA6mfKiNZ9ZiH1DsLZ0ZlQ==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3", + "@vaadin/component-base": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4", "lit": "^2.0.0" } }, "node_modules/@vaadin/icons": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/icons/-/icons-24.1.3.tgz", - "integrity": "sha512-C3++s9EPfTd3StW42SDzzdnPdcteG7RPoBSGLIc4gxBJXhQ0xwphBuHi30kvNDo3Kr2s/GMiUkUgSEpWg9iP6g==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/icons/-/icons-24.1.4.tgz", + "integrity": "sha512-cvhKKRSJscwIgsw/Y3DgnqFu7twKF5C1N6A+SsUZjs5ZhJzKZIv74nF+lWpE1/sVjzSH0LJLoPf8/SDdMOvBYw==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/icon": "~24.1.3" + "@vaadin/icon": "~24.1.4" } }, "node_modules/@vaadin/input-container": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/input-container/-/input-container-24.1.3.tgz", - "integrity": "sha512-keHVFg63nhtrlReEzlnQnsrnCm8LARh0rgcAWA+Ny4SDsh2mmCcUkj5kaEkxnU7XKJtytKN9p0BUtvFk1nfSQQ==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/input-container/-/input-container-24.1.4.tgz", + "integrity": "sha512-DfKTPWkJ0KhGlVRBemaOEoGrabHuhYWLjcG0N7397qH45knl+kmDbZihgZxNy6KB3hoHPCD9ZFwr+YuqZJwipg==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/component-base": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/item": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/item/-/item-24.1.3.tgz", - "integrity": "sha512-kxnnYg2vlfPFwABUo9Ad9mSVa2bdYuE86HxrCFD/41RyKLL6SXEjpmMM6R6Unnn6DgWWEfe0TWGK1E/YZjZIrQ==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/item/-/item-24.1.4.tgz", + "integrity": "sha512-eeGNQtdWz1aZ0JhYKC7nuASK3mSodw4w2FIzcGoLvspUfblxeai3TqPPYrqXGAHOhrR215bqe5/qKjwBQz9gDQ==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/list-box": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/list-box/-/list-box-24.1.3.tgz", - "integrity": "sha512-pyU5yvD5PnJ9huXqu4yTQIC+4Lg64Uk64tXwE/ajVuWF4M8aqDlg0SXXkTDrqkoFVvJNzWFzoGBNQYB0OVNenw==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/list-box/-/list-box-24.1.4.tgz", + "integrity": "sha512-A2jQVqj+Qgs8FO0Ra6AjX7jBqx2oPT10UVyGTI5aA/dK1Q9/ZpAEDMsHa9VFX3cFKGIFpuqHFFCStzNmVyY8ZQ==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/item": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/item": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/lit-renderer": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/lit-renderer/-/lit-renderer-24.1.3.tgz", - "integrity": "sha512-z5JajZFK+9Mznn80dqT7VbigrbNrifS6QpCzQLLwR9XRLc6g1pKSxznMwQ4vkS8b1YmO7mvj/waTbznAaZX4ag==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/lit-renderer/-/lit-renderer-24.1.4.tgz", + "integrity": "sha512-VUYOBQanMHViqqWlJD9mVyAUkLgEhJ7XUmiK5PXAckOTcE9JSI3MlSU0x0Stjos/NTfgXCXzy9XnvBRQezbWGw==", "dev": true, "dependencies": { "lit": "^2.0.0" } }, "node_modules/@vaadin/overlay": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/overlay/-/overlay-24.1.3.tgz", - "integrity": "sha512-U30tYokeawHb5nlzpAvEx13/gEBX7IEljZa/sjj0DsT7zr8agF6HqGIw4/+tARMMlBCw/cYk7/RKAGPD7aYgAw==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/overlay/-/overlay-24.1.4.tgz", + "integrity": "sha512-T0guGVrAET0Ua2Z39GCtpWFzMd4GZqIK1pxzVraa2cZJMA3Zla2Qc10GpLUkCgyLFIiZMGXu+h25BpcaUykMVQ==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/password-field": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/password-field/-/password-field-24.1.3.tgz", - "integrity": "sha512-Gip9tALvcVqnfzQqj7XXTnY+E9dhQ8fQjX8NwNbYRLyeSBYN2UhlvGRwdZt3ldcqHS2+X7aNZfRYAfv/iJAVgg==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/password-field/-/password-field-24.1.4.tgz", + "integrity": "sha512-+iJRSZ1/x1dr2z3SYsUQ66Iic2MdXZXXm83id4sjNDMrO8TcHYmAtxR58CVX5c/T4jQwKgmxnoJsA4m2sZRGAw==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/button": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/text-field": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/button": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/text-field": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/text-field": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/text-field/-/text-field-24.1.3.tgz", - "integrity": "sha512-ESWkup9SPyZBltsQVQyXn6Q8bpGKvHFTy6g8QgVIjxKV9zeHICepMGfIVnrbbYGaZdJk1cdZvc1Vui6G9VT+7Q==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/text-field/-/text-field-24.1.4.tgz", + "integrity": "sha512-FRy9T3iQcioUN2ggrZFtwAs56YQ6pX3wxuP6cAJOZPYzi6eLjFDaAr71HGHRSmWdpCncZv+yLaZy+6frQGJ70A==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/field-base": "~24.1.3", - "@vaadin/input-container": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3", + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/field-base": "~24.1.4", + "@vaadin/input-container": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4", "lit": "^2.0.0" } }, "node_modules/@vaadin/tooltip": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/tooltip/-/tooltip-24.1.3.tgz", - "integrity": "sha512-UOGv5Y4SMGhwvO7ahi5uViLsSppKEFGgmwqKVeEUaSbtdLO/U+CIkdwZpRnFMIj3TKv7T94qoAy1lFKaV2vQvQ==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/tooltip/-/tooltip-24.1.4.tgz", + "integrity": "sha512-lirhnOEp76Whz083JmC+oJbIFIHwyAk5ead1uZdreHRKxTNHa1Hzj07T7MzlzCtY6+8yf9nArqkQdJZdwBwQhw==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.1.3", - "@vaadin/component-base": "~24.1.3", - "@vaadin/overlay": "~24.1.3", - "@vaadin/vaadin-lumo-styles": "~24.1.3", - "@vaadin/vaadin-material-styles": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/a11y-base": "~24.1.4", + "@vaadin/component-base": "~24.1.4", + "@vaadin/overlay": "~24.1.4", + "@vaadin/vaadin-lumo-styles": "~24.1.4", + "@vaadin/vaadin-material-styles": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/vaadin-development-mode-detector": { @@ -4008,30 +4074,30 @@ "dev": true }, "node_modules/@vaadin/vaadin-lumo-styles": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-lumo-styles/-/vaadin-lumo-styles-24.1.3.tgz", - "integrity": "sha512-qO55INd7arl0OYVVehrqUkB1iGUcGOErWQ6c1T4ahxqJo13irm3TtfcHeakn91Pvvz10/tqCbLdhcHa6T3YXBQ==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/vaadin-lumo-styles/-/vaadin-lumo-styles-24.1.4.tgz", + "integrity": "sha512-LwRCno9q3qUBswHUe1fCtb62a9uuMPW5NBLCXZ+B0pnm+tVqytAn5gREzSdmAL9IzhF3Q/pq4PEIp+mlKdIX3g==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/icon": "~24.1.3", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/icon": "~24.1.4", + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/vaadin-material-styles": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-material-styles/-/vaadin-material-styles-24.1.3.tgz", - "integrity": "sha512-tS/2NuT+/pW7rcalXiNShDUIYlctIEzfES19BUULgPfM3wMMCAaKzWRLl7LviyFgQ4kjSUDV2Od8b4HuI9JgBA==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/vaadin-material-styles/-/vaadin-material-styles-24.1.4.tgz", + "integrity": "sha512-2hrkT9Qg9Sk9GH6A+1jSh+GMQHClu0Io3ZhLoENpjGrJprfARcKc/hBpqES4Z5iyfII7xt3sei7xBjPSGKHpUg==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/vaadin-themable-mixin": "~24.1.3" + "@vaadin/vaadin-themable-mixin": "~24.1.4" } }, "node_modules/@vaadin/vaadin-themable-mixin": { - "version": "24.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-themable-mixin/-/vaadin-themable-mixin-24.1.3.tgz", - "integrity": "sha512-7JZ1apJdht9BfV5TCJuGX6yPBvC7ofAzF2zvvlolwMVdm5fRp4P0vrwZ4BZXVKngCjH//CN5R8LXlJmOr2/1+w==", + "version": "24.1.4", + "resolved": "https://registry.npmjs.org/@vaadin/vaadin-themable-mixin/-/vaadin-themable-mixin-24.1.4.tgz", + "integrity": "sha512-FJLiqggz0osHi7HRXiBD0RrqWqa/4OZw3v89aU+JvnJ/gvZxZRVReIg0b+35ltprqnKRN1PbwNNfP8HUkYM1/Q==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", @@ -4058,9 +4124,9 @@ "dev": true }, "node_modules/@xmldom/xmldom": { - "version": "0.8.9", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.9.tgz", - "integrity": "sha512-4VSbbcMoxc4KLjb1gs96SRmi7w4h1SF+fCoiK0XaQX62buCc1G5d0DC5bJ9xJBNPDSVCmIrcl8BiYxzjrqaaJA==", + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -4935,9 +5001,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001515", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz", - "integrity": "sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA==", + "version": "1.0.30001517", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", + "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", "funding": [ { "type": "opencollective", @@ -5583,9 +5649,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", "dev": true, "engines": { "node": ">=8" @@ -5759,9 +5825,9 @@ } }, "node_modules/electron": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-25.3.0.tgz", - "integrity": "sha512-cyqotxN+AroP5h2IxUsJsmehYwP5LrFAOO7O7k9tILME3Sa1/POAg3shrhx4XEnaAMyMqMLxzGvkzCVxzEErnA==", + "version": "25.3.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-25.3.1.tgz", + "integrity": "sha512-t0QXXqgf0/P0OJ9LU3qpcBMK+wL0FRwTQfooBaaG08v5hywPzc1yplfb3l4tS1xC0Ttw8IBaKLBeEoRgxBRHjg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -6162,9 +6228,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.459", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.459.tgz", - "integrity": "sha512-XXRS5NFv8nCrBL74Rm3qhJjA2VCsRFx0OjHKBMPI0otij56aun8UWiKTDABmd5/7GTR021pA4wivs+Ri6XCElg==" + "version": "1.4.468", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.468.tgz", + "integrity": "sha512-6M1qyhaJOt7rQtNti1lBA0GwclPH+oKCmsra/hkcWs5INLxfXXD/dtdnaKUYQu/pjOBP/8Osoe4mAcNvvzoFag==" }, "node_modules/electron-updater": { "version": "6.1.1", @@ -7744,9 +7810,9 @@ } }, "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", "dev": true, "dependencies": { "json-buffer": "3.0.1" @@ -9223,9 +9289,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.19.2.tgz", - "integrity": "sha512-RXl0Waiss4YtJAUY3NzKH0xkJmsZupCIccqcIFoLTIKFlKNbIvFDRl27/kQy1FP8iUAxrjRRfIVvOebnnXJgqQ==", + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.19.3.tgz", + "integrity": "sha512-tgSnwN7BS7/UM0sSARcW+IQryx2vODKX4MI7xpqY2X+iaepJdKBPc7I4aACIsDV/LTaTjt12Z56MhDr9LsyuZQ==", "dependencies": { "orderedmap": "^2.0.0" } @@ -9306,9 +9372,9 @@ } }, "node_modules/prosemirror-view": { - "version": "1.31.5", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.31.5.tgz", - "integrity": "sha512-tobRCDeCp61elR1d97XE/JTL9FDIfswZpWeNs7GKJjAJvWyMGHWYFCq29850p6bbG2bckP+i9n1vT56RifosbA==", + "version": "1.31.6", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.31.6.tgz", + "integrity": "sha512-wwgErp+EWnuW4kGAYKrt90hhOetaoWpYNdOpnuQMXo1m4x/+uhauFeQoCCm8J30ZqAa4LgIER4yzKSO545gRfA==", "dependencies": { "prosemirror-model": "^1.16.0", "prosemirror-state": "^1.0.0", @@ -9700,9 +9766,9 @@ } }, "node_modules/rollup": { - "version": "3.26.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.2.tgz", - "integrity": "sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==", + "version": "3.26.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", + "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -9827,9 +9893,9 @@ } }, "node_modules/sass": { - "version": "1.63.6", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.6.tgz", - "integrity": "sha512-MJuxGMHzaOW7ipp+1KdELtqKbfAWbH7OLIdoSMnVe3EXPMTmxTmlaZDCTsgIpPCs3w99lLo9/zDKkOrJuT5byw==", + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.64.1.tgz", + "integrity": "sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -10462,9 +10528,9 @@ } }, "node_modules/terser": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.0.tgz", - "integrity": "sha512-JpcpGOQLOXm2jsomozdMDpd5f8ZHh1rR48OFgWUH3QsyZcfPgv2qDCYbcDEAYNd4OZRj2bWYKpwdll/udZCk/Q==", + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -11000,6 +11066,17 @@ "fd-slicer": "~1.1.0" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zeed-dom": { "version": "0.9.26", "resolved": "https://registry.npmjs.org/zeed-dom/-/zeed-dom-0.9.26.tgz", diff --git a/package.json b/package.json index 3ab6945e..72ebada4 100644 --- a/package.json +++ b/package.json @@ -51,28 +51,28 @@ "prosemirror-gapcursor": "1.3.2", "prosemirror-history": "1.3.2", "prosemirror-keymap": "1.2.2", - "prosemirror-model": "1.19.2", + "prosemirror-model": "1.19.3", "prosemirror-schema-list": "1.3.0", "prosemirror-state": "1.4.3", "prosemirror-transform": "1.7.3", - "prosemirror-view": "1.31.5", - "sass": "1.63.6", + "prosemirror-view": "1.31.6", + "sass": "1.64.1", "short-unique-id": "4.4.4", "@hapi/hapi": "21.3.2", "@hapi/inert": "7.1.0", "@lit-labs/motion": "1.0.3", - "@tiptap/pm": "2.0.3", - "@tiptap/core": "2.0.3", - "@tiptap/extension-highlight": "2.0.3", - "@tiptap/extension-image": "2.0.3", - "@tiptap/extension-placeholder": "2.0.3", - "@tiptap/extension-underline": "2.0.3", - "@tiptap/html": "2.0.3", - "@tiptap/starter-kit": "2.0.3" + "@tiptap/pm": "2.0.4", + "@tiptap/core": "2.0.4", + "@tiptap/extension-highlight": "2.0.4", + "@tiptap/extension-image": "2.0.4", + "@tiptap/extension-placeholder": "2.0.4", + "@tiptap/extension-underline": "2.0.4", + "@tiptap/html": "2.0.4", + "@tiptap/starter-kit": "2.0.4" }, "devDependencies": { "axios": "1.4.0", - "electron": "25.3.0", + "electron": "25.3.1", "electron-builder": "24.4.0", "electron-packager": "17.1.1", "epml": "0.3.3", @@ -86,7 +86,7 @@ "passive-events-support": "1.1.0", "redux": "4.2.1", "redux-thunk": "2.4.2", - "rollup": "3.26.2", + "rollup": "3.26.3", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-progress": "1.1.2", "rollup-plugin-scss": "3.0.0", @@ -130,19 +130,19 @@ "@qortal/rollup-plugin-web-worker-loader": "1.6.4", "@rollup/plugin-alias": "5.0.0", "@rollup/plugin-babel": "6.0.3", - "@rollup/plugin-commonjs": "25.0.2", + "@rollup/plugin-commonjs": "25.0.3", "@rollup/plugin-node-resolve": "15.1.0", "@rollup/plugin-replace": "5.0.2", "@rollup/plugin-terser": "0.4.3", - "@vaadin/avatar": "24.1.3", - "@vaadin/button": "24.1.3", - "@vaadin/grid": "24.1.3", - "@vaadin/icons": "24.1.3", - "@vaadin/password-field": "24.1.3", - "@vaadin/tooltip": "24.1.3", + "@vaadin/avatar": "24.1.4", + "@vaadin/button": "24.1.4", + "@vaadin/grid": "24.1.4", + "@vaadin/icons": "24.1.4", + "@vaadin/password-field": "24.1.4", + "@vaadin/tooltip": "24.1.4", "@zip.js/zip.js": "2.7.20" }, "engines": { - "node": ">=18.14.0" + "node": ">=18.15.0" } } From 63bd6ac3c4fe2b9c2d3bf351b460dcea3be0b273 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:19:55 +0200 Subject: [PATCH 13/27] Clear cache and reduce api calls --- core/src/components/app-view.js | 28 ++- .../node-management/node-management.src.js | 197 ++++++++---------- 2 files changed, 109 insertions(+), 116 deletions(-) diff --git a/core/src/components/app-view.js b/core/src/components/app-view.js index 412f9a47..a4b705c3 100644 --- a/core/src/components/app-view.js +++ b/core/src/components/app-view.js @@ -7,6 +7,7 @@ import { get, translate, translateUnsafeHTML } from 'lit-translate' import localForage from 'localforage' import { encryptData, decryptData } from '../lockScreen.js' import { setChatLastSeen } from '../redux/app/app-actions.js' +import isElectron from 'is-electron' const chatLastSeen = localForage.createInstance({ name: "chat-last-seen", @@ -427,7 +428,7 @@ class AppView extends connect(store)(LitElement) { constructor() { super() this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.urls = []; + this.urls = [] this.nodeType = '' this.addressInfo = {} this.getAllBalancesLoading = false @@ -649,6 +650,8 @@ class AppView extends connect(store)(LitElement) { addTradeBotRoutes(parentEpml) parentEpml.imReady() + this.clearTheCache() + this.helperMessage = this.renderHelperPass() this.salt = '' @@ -1581,14 +1584,14 @@ class AppView extends connect(store)(LitElement) { } const getChatLastSeen = async () => { - let items = []; + let items = [] await chatLastSeen.iterate(function (value, key, iterationNumber) { - - items.push({ key, timestamp: value }); + items.push({ key, timestamp: value }) }) + store.dispatch(setChatLastSeen(items)) - return items; + return items } await getOpenTradesBTC() @@ -1603,14 +1606,25 @@ class AppView extends connect(store)(LitElement) { await appDelay(1000) await getOpenTradesARRR() await getChatLastSeen() + setInterval(() => { + this.clearTheCache() + }, 60000) } shBalanceTicker() { const targetDiv = this.shadowRoot.getElementById("theTicker") if (targetDiv.style.display !== "none") { - targetDiv.style.display = "none"; + targetDiv.style.display = "none" } else { - targetDiv.style.display = "inline"; + targetDiv.style.display = "inline" + } + } + + async clearTheCache() { + if (!isElectron()) { + } else { + await window.parent.electronAPI.clearMyCache() + console.clear() } } diff --git a/plugins/plugins/core/node-management/node-management.src.js b/plugins/plugins/core/node-management/node-management.src.js index 3524df1a..cd36187c 100644 --- a/plugins/plugins/core/node-management/node-management.src.js +++ b/plugins/plugins/core/node-management/node-management.src.js @@ -34,10 +34,8 @@ class NodeManagement extends LitElement { confPeerMessage: { type: String }, addMintingAccountMessage: { type: String }, removeMintingAccountMessage: { type: String }, - tempMintingAccount: { type: Object }, nodeConfig: { type: Object }, nodeDomain: { type: String }, - myElementId: { type: String }, theme: { type: String, reflect: true } } } @@ -138,15 +136,13 @@ class NodeManagement extends LitElement { this.addPeerMessage = "" this.confPeerMessage = "" this.addMintingAccountMessage = "" - this.tempMintingAccount = {} this.config = { user: { node: {}, }, - }; + } this.nodeConfig = {} this.nodeDomain = "" - this.myElementId = '' this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' } @@ -278,7 +274,7 @@ class NodeManagement extends LitElement {
- `; + ` } firstUpdated() { @@ -311,73 +307,59 @@ class NodeManagement extends LitElement { // Calculate HH MM SS from Milliseconds... const convertMsToTime = (milliseconds) => { - let day, hour, minute, seconds; - seconds = Math.floor(milliseconds / 1000); - minute = Math.floor(seconds / 60); - seconds = seconds % 60; - hour = Math.floor(minute / 60); - minute = minute % 60; - day = Math.floor(hour / 24); - hour = hour % 24; + let day, hour, minute, seconds + seconds = Math.floor(milliseconds / 1000) + minute = Math.floor(seconds / 60) + seconds = seconds % 60 + hour = Math.floor(minute / 60) + minute = minute % 60 + day = Math.floor(hour / 24) + hour = hour % 24 if (isNaN(day)) { - return "offline"; + return "offline" } - return day + "d " + hour + "h " + minute + "m"; - }; + return day + "d " + hour + "h " + minute + "m" + } const getNodeUpTime = () => { - parentEpml - .request("apiCall", { - url: `/admin/uptime`, - }) - .then((res) => { - this.upTime = ""; - setTimeout(() => { - this.upTime = convertMsToTime(res); - }, 1); - }); - - setTimeout(getNodeUpTime, this.config.user.nodeSettings.pingInterval); - }; + this.upTime = "" + parentEpml.request("apiCall", { url: `/admin/uptime` }).then((res) => { + this.upTime = convertMsToTime(res) + }) + setTimeout(getNodeUpTime, 60000) + } const updatePeers = () => { - parentEpml - .request("apiCall", { - url: `/peers`, - }) - .then((res) => { - setTimeout(() => { - this.peers = res; - }, 1); - }); - setTimeout(updatePeers, this.config.user.nodeSettings.pingInterval); - }; + this.peers = [] + parentEpml.request("apiCall", { url: `/peers` }).then((res) => { + this.peers = res + }) + setTimeout(updatePeers, 60000) + } const getNodeConfig = () => { + this.nodeConfig = {} + this.nodeDomain = "" parentEpml.request("getNodeConfig").then((res) => { - setTimeout(() => { - this.nodeConfig = res; - }, 1); - let myNode = window.parent.reduxStore.getState().app.nodeConfig - .knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - this.nodeDomain = myNode.domain + ":" + myNode.port; - }); - - setTimeout(getNodeConfig, 1000); - }; + this.nodeConfig = res + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + this.nodeDomain = myNode.domain + ":" + myNode.port + }) + setTimeout(getNodeConfig, 60000) + } let configLoaded = false parentEpml.ready().then(() => { parentEpml.subscribe("config", async c => { if (!configLoaded) { - setTimeout(getNodeUpTime, 1); - setTimeout(updatePeers, 1); - setTimeout(this.updateMintingAccounts, 1); - setTimeout(getNodeConfig, 1); - configLoaded = true; + setTimeout(getNodeUpTime, 1) + setTimeout(updatePeers, 1) + setTimeout(this.updateMintingAccounts, 1) + setTimeout(getNodeConfig, 1) + configLoaded = true } - this.config = JSON.parse(c); + this.config = JSON.parse(c) }) }) parentEpml.imReady() @@ -386,11 +368,11 @@ class NodeManagement extends LitElement { changeTheme() { const checkTheme = localStorage.getItem('qortalTheme') if (checkTheme === 'dark') { - this.theme = 'dark'; + this.theme = 'dark' } else { - this.theme = 'light'; + this.theme = 'light' } - document.querySelector('html').setAttribute('theme', this.theme); + document.querySelector('html').setAttribute('theme', this.theme) } changeLanguage() { @@ -421,8 +403,8 @@ class NodeManagement extends LitElement { }) .then((res) => { let err3string = get("nodepage.nchange25") - parentEpml.request('showSnackBar', `${err3string}` + peerAddress); - }); + parentEpml.request('showSnackBar', `${err3string}` + peerAddress) + }) } removePeer(peerAddress, rowIndex) { @@ -434,9 +416,9 @@ class NodeManagement extends LitElement { }) .then((res) => { let err4string = get("nodepage.nchange26") - parentEpml.request('showSnackBar', `${err4string}` + peerAddress); - this.peers.splice(rowIndex, 1); - }); + parentEpml.request('showSnackBar', `${err4string}` + peerAddress) + this.peers.splice(rowIndex, 1) + }) } stopNode() { @@ -446,9 +428,9 @@ class NodeManagement extends LitElement { method: "GET" }) .then((res) => { - let err7string = get("nodepage.nchange32") - parentEpml.request('showSnackBar', `${err7string}`); - }); + let err7string = get("nodepage.nchange32") + parentEpml.request('showSnackBar', `${err7string}`) + }) } restartNode() { @@ -458,19 +440,18 @@ class NodeManagement extends LitElement { method: "GET" }) .then((res) => { - let err7string = get("nodepage.nchange34") - parentEpml.request('showSnackBar', `${err7string}`); - }); + let err7string = get("nodepage.nchange34") + parentEpml.request('showSnackBar', `${err7string}`) + }) } onPageNavigation(pageUrl) { - parentEpml.request("setPageUrl", pageUrl); + parentEpml.request("setPageUrl", pageUrl) } addPeer(e) { - this.addPeerLoading = true; - const addPeerAddress = this.shadowRoot.querySelector("#addPeerAddress") - .value; + this.addPeerLoading = true + const addPeerAddress = this.shadowRoot.querySelector("#addPeerAddress").value parentEpml .request("apiCall", { @@ -479,18 +460,16 @@ class NodeManagement extends LitElement { body: addPeerAddress, }) .then((res) => { - this.addPeerMessage = res.message; - this.addPeerLoading = false; - }); + this.addPeerMessage = res.message + this.addPeerLoading = false + }) } addMintingAccount(e) { - this.addMintingAccountLoading = true; - this.addMintingAccountMessage = "Loading..."; + this.addMintingAccountLoading = true + this.addMintingAccountMessage = "Loading..." - this.addMintingAccountKey = this.shadowRoot.querySelector( - "#addMintingAccountKey" - ).value; + this.addMintingAccountKey = this.shadowRoot.querySelector("#addMintingAccountKey").value parentEpml .request("apiCall", { @@ -500,28 +479,28 @@ class NodeManagement extends LitElement { }) .then((res) => { if (res === true) { - this.updateMintingAccounts(); - this.addMintingAccountKey = ""; - this.addMintingAccountMessage = this.renderErr1Text(); - this.addMintingAccountLoading = false; + this.updateMintingAccounts() + this.addMintingAccountKey = "" + this.addMintingAccountMessage = this.renderErr1Text() + this.addMintingAccountLoading = false } else { - this.addMintingAccountKey = ""; - this.addMintingAccountMessage = this.renderErr2Text(); // Corrected an error here thanks to crow (-_-) - this.addMintingAccountLoading = false; + this.addMintingAccountKey = "" + this.addMintingAccountMessage = this.renderErr2Text() // Corrected an error here thanks to crow (-_-) + this.addMintingAccountLoading = false } - }); + }) } updateMintingAccounts() { - parentEpml.request("apiCall", { - url: `/admin/mintingaccounts`, - }).then((res) => { - setTimeout(() => this.mintingAccounts = res, 1); - }); + this.mintingAccounts = [] + parentEpml.request("apiCall", { url: `/admin/mintingaccounts` }).then((res) => { + this.mintingAccounts = res + }) + console.clear() } removeMintingAccount(publicKey) { - this.removeMintingAccountLoading = true; + this.removeMintingAccountLoading = true parentEpml.request("apiCall", { url: `/admin/mintingaccounts?apiKey=${this.getApiKey()}`, @@ -529,28 +508,28 @@ class NodeManagement extends LitElement { body: publicKey, }).then((res) => { if (res === true) { - this.updateMintingAccounts(); - this.removeMintingAccountLoading = false; + this.updateMintingAccounts() + this.removeMintingAccountLoading = false let err5string = get("nodepage.nchange29") - parentEpml.request('showSnackBar', `${err5string}`); + parentEpml.request('showSnackBar', `${err5string}`) } else { - this.removeMintingAccountLoading = false; + this.removeMintingAccountLoading = false let err6string = get("nodepage.nchange30") - parentEpml.request('showSnackBar', `${err6string}`); + parentEpml.request('showSnackBar', `${err6string}`) } - }); + }) } getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - let apiKey = myNode.apiKey; - return apiKey; + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let apiKey = myNode.apiKey + return apiKey } isEmptyArray(arr) { - if (!arr) return true; - return arr.length === 0; + if (!arr) return true + return arr.length === 0 } } -window.customElements.define("node-management", NodeManagement); +window.customElements.define("node-management", NodeManagement) From 360e82e6218902a69ee517cc545ea745af9075a8 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Mon, 24 Jul 2023 14:21:20 +0200 Subject: [PATCH 14/27] Rework Overview and Sponsor --- core/language/de.json | 3 +- core/language/es.json | 3 +- core/language/fr.json | 3 +- core/language/hindi.json | 3 +- core/language/hr.json | 3 +- core/language/hu.json | 3 +- core/language/it.json | 3 +- core/language/jp.json | 3 +- core/language/ko.json | 3 +- core/language/no.json | 3 +- core/language/pl.json | 3 +- core/language/pt.json | 3 +- core/language/ro.json | 3 +- core/language/rs.json | 3 +- core/language/ru.json | 3 +- core/language/us.json | 3 +- core/language/zhc.json | 3 +- core/language/zht.json | 3 +- .../core/overview-page/overview-page-css.js | 2 + .../core/overview-page/overview-page.src.js | 78 +- .../sponsorship-list/sponsorship-list.src.js | 890 +++++++++--------- 21 files changed, 514 insertions(+), 510 deletions(-) diff --git a/core/language/de.json b/core/language/de.json index 1bad4508..b6fbb936 100644 --- a/core/language/de.json +++ b/core/language/de.json @@ -214,7 +214,8 @@ "wp1": "Prägung", "wp2": "Nicht am Prägen", "wp3": "Kerninformationen", - "wp4": "Synchronisiert" + "wp4": "Synchronisiert", + "wp5": "Synchronisierungsstatus" }, "general": { "yes": "Ja", diff --git a/core/language/es.json b/core/language/es.json index c0265f80..e8f2c274 100644 --- a/core/language/es.json +++ b/core/language/es.json @@ -214,7 +214,8 @@ "wp1": "Acuñación", "wp2": "Sin acuñar", "wp3": "Información básica", - "wp4": "Sincronizado" + "wp4": "Sincronizado", + "wp5": "Estado de sincronización" }, "general": { "yes": "Sí", diff --git a/core/language/fr.json b/core/language/fr.json index fbf6931d..0d134291 100644 --- a/core/language/fr.json +++ b/core/language/fr.json @@ -214,7 +214,8 @@ "wp1": "Monnaie", "wp2": "Pas de frappe", "wp3": "Informations de base", - "wp4": "Synchronisé" + "wp4": "Synchronisé", + "wp5": "État de la synchronisation" }, "general": { "yes": "Oui", diff --git a/core/language/hindi.json b/core/language/hindi.json index fd3d282c..36ab28c8 100644 --- a/core/language/hindi.json +++ b/core/language/hindi.json @@ -215,7 +215,8 @@ "wp1": "खनन", "wp2": "नॉट मिंटिंग", "wp3": "मुख्य जानकारी", - "wp4": "सिंक्रोनाइज़्ड" + "wp4": "सिंक्रोनाइज़्ड", + "wp5": "सिंक स्थिति" }, "general": { "yes": "हाँ", diff --git a/core/language/hr.json b/core/language/hr.json index 17b452a9..7a1e82a4 100644 --- a/core/language/hr.json +++ b/core/language/hr.json @@ -214,7 +214,8 @@ "wp1": "Kovanje", "wp2": "Nije kovano", "wp3": "Osnovne informacije", - "wp4": "Sinkronizirano" + "wp4": "Sinkronizirano", + "wp5": "Status sinkronizacije" }, "general": { "yes": "Da", diff --git a/core/language/hu.json b/core/language/hu.json index 817fc0b1..65c1ec2d 100644 --- a/core/language/hu.json +++ b/core/language/hu.json @@ -214,7 +214,8 @@ "wp1": "verés", "wp2": "Nem pénzverés", "wp3": "Alapinformációk", - "wp4": "Szinkronizált" + "wp4": "Szinkronizált", + "wp5": "Szinkronizálás állapota" }, "general": { "yes": "Igen", diff --git a/core/language/it.json b/core/language/it.json index cc91142b..45b5fdd1 100644 --- a/core/language/it.json +++ b/core/language/it.json @@ -214,7 +214,8 @@ "wp1": "Conio", "wp2": "Non conio", "wp3": "Informazioni principali", - "wp4": "Sincronizzato" + "wp4": "Sincronizzato", + "wp5": "Stato sincronizzazione" }, "general": { "yes": "Yes", diff --git a/core/language/jp.json b/core/language/jp.json index 8ad2adc7..ef09fc52 100644 --- a/core/language/jp.json +++ b/core/language/jp.json @@ -216,7 +216,8 @@ "wp1": "ミント", "wp2": "鋳造しない", "wp3": "コア情報", - "wp4": "同期済み" + "wp4": "同期済み", + "wp5": "同期ステータス" }, "general": { "yes": "はい", diff --git a/core/language/ko.json b/core/language/ko.json index d0c9a87d..eb68f8b7 100644 --- a/core/language/ko.json +++ b/core/language/ko.json @@ -214,7 +214,8 @@ "wp1": "조폐", "wp2": "조폐되지 않음", "wp3": "핵심 정보", - "wp4": "동기화됨" + "wp4": "동기화됨", + "wp5": "동기화 상태" }, "general": { "yes": "예", diff --git a/core/language/no.json b/core/language/no.json index f464c159..55823220 100644 --- a/core/language/no.json +++ b/core/language/no.json @@ -214,7 +214,8 @@ "wp1": "Minting", "wp2": "Ikke preging", "wp3": "Kjerneinformasjon", - "wp4": "Synkronisert" + "wp4": "Synkronisert", + "wp5": "Synkroniseringsstatus" }, "general": { "yes": "Ja", diff --git a/core/language/pl.json b/core/language/pl.json index ee52e236..311a8817 100644 --- a/core/language/pl.json +++ b/core/language/pl.json @@ -214,7 +214,8 @@ "wp1": "Bicie", "wp2": "Nie bije", "wp3": "Podstawowe informacje", - "wp4": "Zsynchronizowany" + "wp4": "Zsynchronizowany", + "wp5": "Stan synchronizacji" }, "general": { "yes": "Tak", diff --git a/core/language/pt.json b/core/language/pt.json index dbdd62af..120079d1 100644 --- a/core/language/pt.json +++ b/core/language/pt.json @@ -214,7 +214,8 @@ "wp1": "Criação", "wp2": "Não está cunhando", "wp3": "Informações essenciais", - "wp4": "Sincronizado" + "wp4": "Sincronizado", + "wp5": "Status da sincronização" }, "general": { "yes": "Sim", diff --git a/core/language/ro.json b/core/language/ro.json index 8a4b2d86..2bef7a2d 100644 --- a/core/language/ro.json +++ b/core/language/ro.json @@ -214,7 +214,8 @@ "wp1": "Battering", "wp2": "Nu se bate", "wp3": "Informații de bază", - "wp4": "Sincronizat" + "wp4": "Sincronizat", + "wp5": "Stare sincronizare" }, "general": { "yes": "Da", diff --git a/core/language/rs.json b/core/language/rs.json index ca92d273..fb214346 100644 --- a/core/language/rs.json +++ b/core/language/rs.json @@ -214,7 +214,8 @@ "wp1": "Kovanje", "wp2": "Ne kuje", "wp3": "Osnovne informacije", - "wp4": "Sinhronizovano" + "wp4": "Sinhronizovano", + "wp5": "Status sinhronizacije" }, "general": { "yes": "Da", diff --git a/core/language/ru.json b/core/language/ru.json index 775174b6..21b24a99 100644 --- a/core/language/ru.json +++ b/core/language/ru.json @@ -214,7 +214,8 @@ "wp1": "Чеканка", "wp2": "Не чеканить", "wp3": "Основная информация", - "wp4": "Синхронизировано" + "wp4": "Синхронизировано", + "wp5": "Статус синхронизации" }, "general": { "yes": "Да", diff --git a/core/language/us.json b/core/language/us.json index 0a6b6dea..b9e03682 100644 --- a/core/language/us.json +++ b/core/language/us.json @@ -215,7 +215,8 @@ "wp1": "Minting", "wp2": "Not Minting", "wp3": "Core Information", - "wp4": "Synchronized" + "wp4": "Synchronized", + "wp5": "Sync Status" }, "general": { "yes": "Yes", diff --git a/core/language/zhc.json b/core/language/zhc.json index 351e379f..55b0c839 100644 --- a/core/language/zhc.json +++ b/core/language/zhc.json @@ -214,7 +214,8 @@ "wp1": "铸造", "wp2": "不铸造", "wp3": "核心信息", - "wp4": "已同步" + "wp4": "已同步", + "wp5": "同步状态" }, "general": { "yes": "是", diff --git a/core/language/zht.json b/core/language/zht.json index d217bf99..89fa0e8a 100644 --- a/core/language/zht.json +++ b/core/language/zht.json @@ -214,7 +214,8 @@ "wp1": "鑄造", "wp2": "不鑄造", "wp3": "核心信息", - "wp4": "已同步" + "wp4": "已同步", + "wp5": "同步狀態" }, "general": { "yes": "是", diff --git a/plugins/plugins/core/overview-page/overview-page-css.js b/plugins/plugins/core/overview-page/overview-page-css.js index 1fab3397..a5fe82e8 100644 --- a/plugins/plugins/core/overview-page/overview-page-css.js +++ b/plugins/plugins/core/overview-page/overview-page-css.js @@ -79,6 +79,8 @@ a:not([href]):not([tabindex]):focus { img { vertical-align: middle; border-style: none; + height: 128px; + width: 128px; } caption { diff --git a/plugins/plugins/core/overview-page/overview-page.src.js b/plugins/plugins/core/overview-page/overview-page.src.js index d0f95ecd..792fcba3 100644 --- a/plugins/plugins/core/overview-page/overview-page.src.js +++ b/plugins/plugins/core/overview-page/overview-page.src.js @@ -1,13 +1,15 @@ import { LitElement, html, css } from 'lit' import { Epml } from '../../../epml.js' import { use, get, translate, registerTranslateConfig } from 'lit-translate' -import isElectron from 'is-electron' import { overviewStyle } from './overview-page-css.js' import { asyncReplace } from 'lit/directives/async-replace.js' +import isElectron from 'is-electron' + import "@material/mwc-button" import '@material/mwc-dialog' -import '@vaadin/button'; import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/button' + registerTranslateConfig({ loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()), @@ -15,8 +17,8 @@ registerTranslateConfig({ async function* countDown(count, callback) { while (count > 0) { - yield count--; - await new Promise((r) => setTimeout(r, 1000)); + yield count-- + await new Promise((r) => setTimeout(r, 1000)) if (count === 0) { callback() } @@ -114,7 +116,7 @@ class OverviewPage extends LitElement {
${this.renderSyncStatus()} - ${translate("walletpage.wchange41")} + ${translate("walletprofile.wp5")}
@@ -168,14 +170,18 @@ class OverviewPage extends LitElement { setInterval(() => { this.refreshItems() }, 60000) + + setInterval(() => { + this.getAvatar() + }, 180000) } changeTheme() { const checkTheme = localStorage.getItem('qortalTheme') if (checkTheme === 'dark') { - this.theme = 'dark'; + this.theme = 'dark' } else { - this.theme = 'light'; + this.theme = 'light' } document.querySelector('html').setAttribute('theme', this.theme) } @@ -288,7 +294,7 @@ class StartMintingNow extends LitElement { status: { type: Number }, timer: { type: Number }, privateRewardShareKey: { type: String } - }; + } } static get styles() { @@ -424,24 +430,24 @@ class StartMintingNow extends LitElement { color: var(--error); } `, - ]; + ] } constructor() { - super(); - this.mintingAccountData = []; - this.errorMsg = ''; - this.openDialogRewardShare = false; - this.status = 0; - this.privateRewardShareKey = ""; + super() + this.mintingAccountData = [] + this.errorMsg = '' + this.openDialogRewardShare = false + this.status = 0 + this.privateRewardShareKey = "" } render() { - return html` ${this.renderStartMintingButton()} `; + return html` ${this.renderStartMintingButton()} ` } firstUpdated() { - this.getMintingAcccounts(); + this.getMintingAcccounts() } renderErrorMsg1() { @@ -465,7 +471,7 @@ class StartMintingNow extends LitElement { const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port const url = `${nodeUrl}/admin/mintingaccounts` try { - const res = await fetch(url); + const res = await fetch(url) const mintingAccountData = await res.json() this.mintingAccountData = mintingAccountData @@ -509,7 +515,7 @@ class StartMintingNow extends LitElement { } } catch (error) { this.errorMsg = this.renderErrorMsg2() - return; + return } try { @@ -540,7 +546,7 @@ class StartMintingNow extends LitElement { } if (!stop) { - stop = true; + stop = true try { const address = window.parent.reduxStore.getState().app?.selectedAddress?.address const myRewardShareArray = await rewardShares(address) @@ -554,7 +560,7 @@ class StartMintingNow extends LitElement { } stop = false } - }; + } interval = setInterval(getAnswer, 5000) } @@ -570,7 +576,7 @@ class StartMintingNow extends LitElement { const isMinterButKeyMintingKeyNotAssigned = addressInfo?.error !== 124 && addressInfo?.level >= 1 && !findMintingAccount const makeTransactionRequest = async (lastRef) => { - let mylastRef = lastRef; + let mylastRef = lastRef let rewarddialog1 = get('transactions.rewarddialog1') let rewarddialog2 = get('transactions.rewarddialog2') let rewarddialog3 = get('transactions.rewarddialog3') @@ -594,18 +600,18 @@ class StartMintingNow extends LitElement { } const getTxnRequestResponse = (txnResponse) => { - let err6string = get('rewardsharepage.rchange21'); + let err6string = get('rewardsharepage.rchange21') if (txnResponse?.extraData?.rewardSharePrivateKey && (txnResponse?.data?.message?.includes('multiple') || txnResponse?.data?.message?.includes('SELF_SHARE_EXISTS'))) { return err6string } if (txnResponse.success === false && txnResponse.message) { - throw (txnResponse); + throw (txnResponse) } else if ( txnResponse.success === true && !txnResponse.data.error ) { - return err6string; + return err6string } else { throw (txnResponse) } @@ -617,7 +623,7 @@ class StartMintingNow extends LitElement { let myTransaction = await makeTransactionRequest(lastRef) - getTxnRequestResponse(myTransaction); + getTxnRequestResponse(myTransaction) return myTransaction?.extraData?.rewardSharePrivateKey } @@ -637,7 +643,7 @@ class StartMintingNow extends LitElement { if(findMintingAccountsFromUser.length > 2){ this.errorMsg = translate("startminting.smchange10") - return; + return } try { @@ -646,7 +652,7 @@ class StartMintingNow extends LitElement { } catch (error) { console.log({ error }) this.errorMsg = error?.data?.message || this.renderErrorMsg4() - return; + return } } @@ -741,7 +747,7 @@ class StartMintingNow extends LitElement { ` : ""} ` : ''} - `; + ` } } window.customElements.define('start-minting-now', StartMintingNow) @@ -751,7 +757,7 @@ class MyButton extends LitElement { onClick: { type: Function }, isLoading: { type: Boolean }, label: { type: String }, - }; + } static styles = css` vaadin-button { @@ -769,13 +775,13 @@ class MyButton extends LitElement { vaadin-button:hover { opacity: 0.9; } - `; + ` constructor() { - super(); - this.onClick = () => {}; - this.isLoading = false; - this.label = ''; + super() + this.onClick = () => {} + this.isLoading = false + this.label = '' } render() { @@ -788,7 +794,7 @@ class MyButton extends LitElement { ? html`${this.label}` : html``} - `; + ` } } customElements.define('my-button', MyButton) \ No newline at end of file diff --git a/plugins/plugins/core/sponsorship-list/sponsorship-list.src.js b/plugins/plugins/core/sponsorship-list/sponsorship-list.src.js index 7e565213..8f1470e9 100644 --- a/plugins/plugins/core/sponsorship-list/sponsorship-list.src.js +++ b/plugins/plugins/core/sponsorship-list/sponsorship-list.src.js @@ -1,33 +1,30 @@ -import { LitElement, html } from "lit" -import { Epml } from "../../../epml.js" -import "../components/ButtonIconCopy.js" -import { use, get, translate, registerTranslateConfig } from "lit-translate" -import { blocksNeed } from "../../utils/blocks-needed.js" -import "../components/ButtonIconCopy.js" +import { LitElement, html } from 'lit' +import { Epml } from '../../../epml.js' +import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' +import { blocksNeed } from '../../utils/blocks-needed.js' +import { asyncReplace } from 'lit/directives/async-replace.js' +import { pageStyles } from './sponsorship-list-css.src.js' import isElectron from 'is-electron' registerTranslateConfig({ loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()), }) -import "@polymer/paper-spinner/paper-spinner-lite.js" -import "@material/mwc-button" +import '@material/mwc-button' +import '@material/mwc-dialog' import '@material/mwc-icon' import '@material/mwc-icon-button' -import "@material/mwc-textfield" -import "@vaadin/button" -import "@polymer/paper-spinner/paper-spinner-lite.js" -import '@material/mwc-dialog' -import {asyncReplace} from 'lit/directives/async-replace.js'; +import '@material/mwc-textfield' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/button' +import '../components/ButtonIconCopy.js' -import { pageStyles } from "./sponsorship-list-css.src.js" - -const parentEpml = new Epml({ type: "WINDOW", source: window.parent }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) async function* countDown(count, callback) { while (count > 0) { - yield count--; - await new Promise((r) => setTimeout(r, 1000)); + yield count-- + await new Promise((r) => setTimeout(r, 1000)) if(count === 0) { callback() } @@ -64,29 +61,356 @@ class SponsorshipList extends LitElement { constructor() { super() - this.theme = localStorage.getItem("qortalTheme") ? localStorage.getItem("qortalTheme") : "light" + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' this.isPageLoading = true this.nodeInfo = {} this.addressInfo = {} - this.rewardSharePublicKey = "" + this.rewardSharePublicKey = '' this.mintingAccountData = null this.sponsorships = [] this.removeRewardShareLoading = false - this.errorMessage = "" + this.errorMessage = '' this.isLoadingCreateSponsorship = false - this.publicKeyValue = "" + this.publicKeyValue = '' this.isOpenModal = false this.status = 0 - this.privateRewardShareKey = "" + this.privateRewardShareKey = '' this.openDialogRewardShare = false this.isOpenDialogPublicKeyLookup = false - this.lookupAddressValue = "" - this.lookupPublicAddressValue = "" - this.errorLookup = "" + this.lookupAddressValue = '' + this.lookupPublicAddressValue = '' + this.errorLookup = '' + } + + render() { + return html` + ${ + this.isPageLoading + ? html` +
+
+
+
+ ` + : '' + } + +
+

+ ${translate('mintingpage.mchange35')} +

+
+
+
+
+ ${this.sponsorships.length === 0 ? html` +
+

${translate('sponsorshipspage.schange9')}

+
+ ` : ''} + ${this.sponsorships.length > 0 ? html` +
+

${translate('sponsorshipspage.schange1')}

+
+
+
+

${translate('settings.account')}

+
+
+

${translate('walletprofile.blocksminted')}

+
+
+

${translate('sponsorshipspage.schange19')}

+
+
+

${translate('sponsorshipspage.schange21')}

+
+
+ ${this.sponsorships.map((sponsorship) => html` +
    +
  • +
    + ${sponsorship?.name ? html` + + ` : ''} + ${sponsorship?.name || sponsorship.address} +
    +
  • +
  • + ${+sponsorship.blocksMinted + + +sponsorship.blocksMintedAdjustment} +
  • +
  • + {this.createRewardShare(sponsorship?.publicKey, true)}} + > + content_copy ${translate('sponsorshipspage.schange11')} + +
  • +
  • + this.removeRewardShare(sponsorship)} + > + delete_forever ${translate('rewardsharepage.rchange17')} + +
  • +
+ `)} + +
+

+ ${translate('sponsorshipspage.schange3')}  + + ${this.sponsorships.length} + +

+

+ ${translate('sponsorshipspage.schange4')}  + + ${this.nextSponsorshipEnding + ?.blocksRemaining}  + + ${translate('mintingpage.mchange26')} +

+
+ ` : ''} +

${this.errorMessage}

+
+ + +
+ + +
+ +
+ + ${translate('puzzlepage.pchange15')} + +
+ +
+ + ${translate('sponsorshipspage.schange10')} + +
+
+
+ + +
+

${translate('sponsorshipspage.schange6')}

+
+
+
+

${this.sponsorships.filter(s=> s.blocksRemaining <= 0).length} ${translate('sponsorshipspage.schange7')}!

+

${translate('sponsorshipspage.schange8')}

+ ${this.sponsorships.filter(s=> s.blocksRemaining <= 0).map((ms)=> html` +

${ms.address}

+ `)} +
+ + ${translate('general.close')} + +
+ + +
+
+

${translate('sponsorshipspage.schange14')}

+
3 && 'hide'}`}>
+
+
+
+
+
    +
  • +

    + 1. ${translate('sponsorshipspage.schange20')} +

    +
    +
  • +
  • +

    + 2. ${translate('startminting.smchange6')} +

    +
    +
  • +
  • +

    + 3. ${translate('sponsorshipspage.schange15')} +

    +
    +
    ${asyncReplace(this.timer)} +
    +
  • +
  • +

    + 4. ${translate('startminting.smchange9')} +

    +
  • + ${this.privateRewardShareKey && this.status === 4 ? html` +
  • +

    + ${translate('sponsorshipspage.schange16')} +

    +
    + ${this.privateRewardShareKey} +
    + {this.saveToClipboard(this.privateRewardShareKey, this.renderCopyMsg())}} + > + ${translate('sponsorshipspage.schange11')} + +
  • + ` : ''} +
+ ${this.status === 4 ? '' : html` +
+

+ ${translate('sponsorshipspage.schange18')} +

+

${this.errorMessage}

+
+ `} +
+ { + this.openDialogRewardShare = false + this.errorMessage = '' + this.isLoadingCreateSponsorship = false + this.privateRewardShareKey = '' + this.atMount() + }} + class='red' + > + ${translate('general.close')} + +
+ + +
+

${translate('sponsorshipspage.schange10')}

+
+
+
+

+ ${translate('sponsorshipspage.schange12')} +

+
+ + +
+

${this.errorLookup}

+
+ + ${translate('sponsorshipspage.schange10')} + +
+ ${this.lookupPublicAddressValue ? html` +
+ ${this.lookupPublicAddressValue} +
+
+ {this.saveToClipboard(this.lookupPublicAddressValue, this.renderCopyMsg())}} + > + ${translate('sponsorshipspage.schange11')} + +
+ ` : ''} +
+ { + this.lookupAddressValue = '' + this.lookupPublicAddressValue = '' + this.isOpenDialogPublicKeyLookup = false + this.errorLookup = '' + + }} + > + ${translate('general.close')} + +
+
+ ` + } + + async firstUpdated() { + this.changeTheme() + this.changeLanguage() + await this.atMount() + + window.addEventListener('storage', () => { + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } } renderCopyMsg() { - let copystring = get("sponsorshipspage.schange17") + let copystring = get('sponsorshipspage.schange17') return `${copystring}` } @@ -98,46 +422,30 @@ class SponsorshipList extends LitElement { this.lookupAddressValue = e.target.value } - changeLanguage() { - const checkLanguage = localStorage.getItem("qortalLanguage") + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + } + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') if (checkLanguage === null || checkLanguage.length === 0) { - localStorage.setItem("qortalLanguage", "us") - use("us") + localStorage.setItem('qortalLanguage', 'us') + use('us') } else { use(checkLanguage) } } - _handleStorage() { - const checkLanguage = localStorage.getItem("qortalLanguage") - const checkTheme = localStorage.getItem("qortalTheme") - - use(checkLanguage) - - if (checkTheme === "dark") { - this.theme = "dark" - } else { - this.theme = "light" - } - document.querySelector("html").setAttribute("theme", this.theme) - } - - connectedCallback() { - super.connectedCallback() - window.addEventListener("storage", this._handleStorage) - } - - disconnectedCallback() { - window.removeEventListener("storage", this._handleStorage) - super.disconnectedCallback() - } - async getNodeInfo() { - const nodeInfo = await parentEpml.request("apiCall", { - url: `/admin/status`, + const nodeInfo = await parentEpml.request('apiCall', { + url: `/admin/status` }) - return nodeInfo } @@ -149,26 +457,23 @@ class SponsorshipList extends LitElement { console.error('Copy to clipboard error:', err) } } - changeStatus(value){ + + changeStatus(value) { this.status = value - let copystring1 = get("sponsorshipspage.schange17") + let copystring1 = get('sponsorshipspage.schange17') this.saveToClipboard(this.privateRewardShareKey, `${copystring1}`) } getApiKey() { - const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - let apiKey = apiNode.apiKey; - return apiKey; + const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let apiKey = apiNode.apiKey + return apiKey } async atMount() { - - this.changeLanguage() - this.addressInfo = window.parent.reduxStore.getState().app.accountInfo.addressInfo this.isPageLoading = true try { - const address = window.parent.reduxStore.getState().app?.selectedAddress?.address let rewardShares = await this.getRewardShareRelationship(address) @@ -176,17 +481,17 @@ class SponsorshipList extends LitElement { rewardShares = rewardShares.filter((rs) => rs.recipient !== address) const getAccountInfo = rewardShares.map(async (rs) => { - const addressInfo = await parentEpml.request("apiCall", { - type: "api", - url: `/addresses/${rs.recipient}`, + const addressInfo = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/${rs.recipient}` }) - const getNames = await parentEpml.request("apiCall", { - type: "api", - url: `/names/address/${rs.recipient}`, + const getNames = await parentEpml.request('apiCall', { + type: 'api', + url: `/names/address/${rs.recipient}` }) - let url = "" - if(getNames?.length > 0 ){ + let url = '' + if(getNames?.length > 0 ) { const avatarNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port const urlPic = `${avatarUrl}/arbitrary/THUMBNAIL/${getNames[0].name}/qortal_avatar?async=true&apiKey=${this.getApiKey()}` @@ -215,47 +520,31 @@ class SponsorshipList extends LitElement { this.isPageLoading = false const openModal = accountInfoValues.find(s=> s.blocksRemaining <= 0) - if(openModal){ + if(openModal) { this.shadowRoot.querySelector('#showDialog').show() } } catch (error) { - this.isPageLoading = false } } - async firstUpdated() { - await this.atMount() - if (!isElectron()) { - } else { - window.addEventListener('contextmenu', (event) => { - event.preventDefault() - window.parent.electronAPI.showMyMenu() - }) - } - } - async getRewardShareRelationship(recipientAddress) { - const myRewardShareArray = await parentEpml.request("apiCall", { - type: "api", - url: `/addresses/rewardshares?minters=${recipientAddress}`, + const myRewardShareArray = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/rewardshares?minters=${recipientAddress}` }) return myRewardShareArray } _levelUpBlocks(accountInfo) { - let countBlocksString = ( - blocksNeed(0) - - (accountInfo?.blocksMinted + accountInfo?.blocksMintedAdjustment) - ).toString() + let countBlocksString = (blocksNeed(0) - (accountInfo?.blocksMinted + accountInfo?.blocksMintedAdjustment)).toString() return countBlocksString } async removeRewardShare(rewardShareObject) { - const selectedAddress = - window.parent.reduxStore.getState().app?.selectedAddress + const selectedAddress = window.parent.reduxStore.getState().app?.selectedAddress const myPercentageShare = -1 @@ -264,9 +553,9 @@ class SponsorshipList extends LitElement { // Get Last Ref const getLastRef = async () => { - let myRef = await parentEpml.request("apiCall", { - type: "api", - url: `/addresses/lastreference/${selectedAddress?.address}`, + let myRef = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${selectedAddress?.address}` }) return myRef } @@ -282,14 +571,14 @@ class SponsorshipList extends LitElement { // Make Transaction Request const makeTransactionRequest = async (lastRef) => { let mylastRef = lastRef - let rewarddialog5 = get("transactions.rewarddialog5") - let rewarddialog6 = get("transactions.rewarddialog6") - let myTxnrequest = await parentEpml.request("transaction", { + let rewarddialog5 = get('transactions.rewarddialog5') + let rewarddialog6 = get('transactions.rewarddialog6') + let myTxnrequest = await parentEpml.request('transaction', { type: 381, nonce: selectedAddress?.nonce, params: { rewardShareKeyPairPublicKey: - rewardShareObject.rewardSharePublicKey, + rewardShareObject.rewardSharePublicKey, recipient: rewardShareObject.recipient, percentageShare: myPercentageShare, lastReference: mylastRef, @@ -303,19 +592,19 @@ class SponsorshipList extends LitElement { const getTxnRequestResponse = (txnResponse) => { if (txnResponse.success === false && txnResponse.message) { this.removeRewardShareLoading = false - parentEpml.request("showSnackBar", txnResponse.message) + parentEpml.request('showSnackBar', txnResponse.message) throw new Error(txnResponse) } else if ( txnResponse.success === true && !txnResponse.data.error ) { - let err7tring = get("rewardsharepage.rchange22") + let err7tring = get('rewardsharepage.rchange22') this.removeRewardShareLoading = false - parentEpml.request("showSnackBar", `${err7tring}`) + parentEpml.request('showSnackBar', `${err7tring}`) this.sponsorships = this.sponsorships.filter((s)=> s.address !== rewardShareObject.address) } else { this.removeRewardShareLoading = false - parentEpml.request("showSnackBar", txnResponse.data.message) + parentEpml.request('showSnackBar', txnResponse.data.message) throw new Error(txnResponse) } } @@ -324,12 +613,12 @@ class SponsorshipList extends LitElement { async createRewardShare(publicKeyValue, isCopy) { this.openDialogRewardShare = true - if(!publicKeyValue){ - this.errorMessage = "unable to pull public key from the chain, account has no outgoing transactions" + if(!publicKeyValue) { + this.errorMessage = 'unable to pull public key from the chain, account has no outgoing transactions' return } - this.privateRewardShareKey = "" - this.errorMessage = "" + this.privateRewardShareKey = '' + this.errorMessage = '' const recipientPublicKey = publicKeyValue const percentageShare = 0 const selectedAddress = window.parent.reduxStore.getState().app?.selectedAddress @@ -339,18 +628,18 @@ class SponsorshipList extends LitElement { // Get Last Ref const getLastRef = async () => { - let myRef = await parentEpml.request("apiCall", { - type: "api", - url: `/addresses/lastreference/${selectedAddress.address}`, + let myRef = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${selectedAddress.address}` }) return myRef } // Get Account Details const getAccountDetails = async () => { - let myAccountDetails = await parentEpml.request("apiCall", { - type: "api", - url: `/addresses/${selectedAddress.address}`, + let myAccountDetails = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/${selectedAddress.address}` }) return myAccountDetails } @@ -361,28 +650,23 @@ class SponsorshipList extends LitElement { try { accountDetails = await getAccountDetails() } catch (error) { - this.errorMessage = "Couldn't fetch account details" + this.errorMessage = 'Couldn't fetch account details' } let lastRef = await getLastRef() if (accountDetails.level >= 5 || accountDetails.flags === 1) { this.status = 1 - this.errorMessage = "" + this.errorMessage = '' try { const myTransaction = await makeTransactionRequest(lastRef) - - getTxnRequestResponse(myTransaction) } catch (error) { this.errorMessage = error } - - } else { - - let err5string = get("rewardsharepage.rchange20") + let err5string = get('rewardsharepage.rchange20') this.errorMessage = `${err5string} ${accountDetails.level}` } @@ -391,11 +675,11 @@ class SponsorshipList extends LitElement { // Make Transaction Request const makeTransactionRequest = async (lastRef) => { let mylastRef = lastRef - let rewarddialog1 = get("transactions.rewarddialog1") - let rewarddialog2 = get("transactions.rewarddialog2") - let rewarddialog3 = get("transactions.rewarddialog3") - let rewarddialog4 = get("transactions.rewarddialog4") - let myTxnrequest = await parentEpml.request("transaction", { + let rewarddialog1 = get('transactions.rewarddialog1') + let rewarddialog2 = get('transactions.rewarddialog2') + let rewarddialog3 = get('transactions.rewarddialog3') + let rewarddialog4 = get('transactions.rewarddialog4') + let myTxnrequest = await parentEpml.request('transaction', { type: 38, nonce: selectedAddress.nonce, params: { @@ -413,7 +697,7 @@ class SponsorshipList extends LitElement { } const getTxnRequestResponse = (txnResponse) => { - if(txnResponse?.extraData?.rewardSharePrivateKey && (txnResponse?.data?.message?.includes('multiple') || txnResponse?.data?.message?.includes('SELF_SHARE_EXISTS')) ){ + if(txnResponse?.extraData?.rewardSharePrivateKey && (txnResponse?.data?.message?.includes('multiple') || txnResponse?.data?.message?.includes('SELF_SHARE_EXISTS'))) { this.privateRewardShareKey = txnResponse?.extraData?.rewardSharePrivateKey this.confirmRelationship(publicKeyValue, isCopy) } else if (txnResponse.success === false && txnResponse?.message) { @@ -435,7 +719,7 @@ class SponsorshipList extends LitElement { validateReceiver() } - async confirmRelationship(recipientPublicKey, isCopy){ + async confirmRelationship(recipientPublicKey, isCopy) { this.status = 2 let interval = null let stop = false @@ -443,45 +727,38 @@ class SponsorshipList extends LitElement { const getAnswer = async () => { if (!stop) { - stop= true; + stop= true try { - - const recipientAddress = - window.parent.base58PublicKeyToAddress(recipientPublicKey) - + const recipientAddress = window.parent.base58PublicKeyToAddress(recipientPublicKey) const minterAddress = window.parent.reduxStore.getState().app?.selectedAddress.address - const myRewardShareArray = await parentEpml.request("apiCall", { - type: "api", - url: `/addresses/rewardshares?minters=${minterAddress}&recipients=${recipientAddress}`, - }) - if(myRewardShareArray.length > 0){ + const myRewardShareArray = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/rewardshares?minters=${minterAddress}&recipients=${recipientAddress}` + }) + if(myRewardShareArray.length > 0) { clearInterval(interval) this.status = 3 - - - this.timer = countDown(isCopy ? 5 : 180, ()=> this.changeStatus(4)); - } - + this.timer = countDown(isCopy ? 5 : 180, ()=> this.changeStatus(4)) + } } catch (error) { console.error(error) - } stop = false } - }; - interval = setInterval(getAnswer, 5000); + } + interval = setInterval(getAnswer, 5000) } - async lookUpPublicAddressFunc(){ + async lookUpPublicAddressFunc() { this.errorLookup = '' try { - const response = await parentEpml.request("apiCall", { - type: "api", - url: `/addresses/publickey/${this.lookupAddressValue}`, + const response = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/publickey/${this.lookupAddressValue}` }) - if(response.error){ + if(response.error) { throw(response.message) } this.lookupPublicAddressValue = response @@ -490,305 +767,6 @@ class SponsorshipList extends LitElement { console.error(error) } } - - render() { - return html` - ${ - this.isPageLoading - ? html` -
-
-
-
- ` - : "" - } - -
-

- ${translate("mintingpage.mchange35")} -

-
-
-
-
- ${this.sponsorships.length === 0 ? html` -
-

${translate("sponsorshipspage.schange9")}

-
- ` : ''} - ${this.sponsorships.length > 0 ? html` -
-

${translate("sponsorshipspage.schange1")}

-
-
-
-

${translate("settings.account")}

-
-
-

${translate("walletprofile.blocksminted")}

-
-
-

${translate("sponsorshipspage.schange19")}

-
-
-

${translate("sponsorshipspage.schange21")}

-
-
- ${this.sponsorships.map((sponsorship) => html` -
    -
  • -
    - ${sponsorship?.name ? html` - - ` : ''} - ${sponsorship?.name || sponsorship.address} -
    -
  • -
  • - ${+sponsorship.blocksMinted + - +sponsorship.blocksMintedAdjustment} -
  • -
  • - {this.createRewardShare(sponsorship?.publicKey, true)}} - > - content_copy ${translate("sponsorshipspage.schange11")} - -
  • -
  • - this.removeRewardShare(sponsorship)} - > - delete_forever ${translate("rewardsharepage.rchange17")} - -
  • -
- `)} - -
-

- ${translate("sponsorshipspage.schange3")}  - - ${this.sponsorships.length} - -

-

- ${translate("sponsorshipspage.schange4")}  - - ${this.nextSponsorshipEnding - ?.blocksRemaining}  - - ${translate("mintingpage.mchange26")} -

-
- ` : ''} -

${this.errorMessage}

-
- - -
- - -
- -
- - ${translate("puzzlepage.pchange15")} - -
- -
- - ${translate("sponsorshipspage.schange10")} - -
-
-
- - -
-

${translate("sponsorshipspage.schange6")}

-
-
-
-

${this.sponsorships.filter(s=> s.blocksRemaining <= 0).length} ${translate("sponsorshipspage.schange7")}!

-

${translate("sponsorshipspage.schange8")}

- ${this.sponsorships.filter(s=> s.blocksRemaining <= 0).map((ms)=> html` -

${ms.address}

- `)} -
- - ${translate("general.close")} - -
- - -
-
-

${translate("sponsorshipspage.schange14")}

-
3 && 'hide'}`}>
-
-
-
-
-
    -
  • -

    - 1. ${translate("sponsorshipspage.schange20")} -

    -
    -
  • -
  • -

    - 2. ${translate("startminting.smchange6")} -

    -
    -
  • -
  • -

    - 3. ${translate("sponsorshipspage.schange15")} -

    -
    -
    ${asyncReplace(this.timer)} -
    -
  • -
  • -

    - 4. ${translate("startminting.smchange9")} -

    -
  • - ${this.privateRewardShareKey && this.status === 4 ? html` -
  • -

    - ${translate("sponsorshipspage.schange16")} -

    -
    - ${this.privateRewardShareKey} -
    - {this.saveToClipboard(this.privateRewardShareKey, this.renderCopyMsg())}} - > - ${translate("sponsorshipspage.schange11")} - -
  • - ` : ''} -
- ${this.status === 4 ? '' : html` -
-

- ${translate("sponsorshipspage.schange18")} -

-

${this.errorMessage}

-
- `} -
- { - this.openDialogRewardShare = false - this.errorMessage = '' - this.isLoadingCreateSponsorship = false - this.privateRewardShareKey = "" - this.atMount() - }} - class="red" - > - ${translate("general.close")} - -
- - -
-

${translate("sponsorshipspage.schange10")}

-
-
-
-

- ${translate("sponsorshipspage.schange12")} -

-
- - -
-

${this.errorLookup}

-
- - ${translate("sponsorshipspage.schange10")} - -
- ${this.lookupPublicAddressValue ? html` -
- ${this.lookupPublicAddressValue} -
-
- {this.saveToClipboard(this.lookupPublicAddressValue, this.renderCopyMsg())}} - > - ${translate("sponsorshipspage.schange11")} - -
- ` : ''} -
- { - this.lookupAddressValue = "" - this.lookupPublicAddressValue = "" - this.isOpenDialogPublicKeyLookup = false - this.errorLookup = "" - - }} - > - ${translate("general.close")} - -
-
- ` - } } -window.customElements.define("sponsorship-list", SponsorshipList) +window.customElements.define('sponsorship-list', SponsorshipList) From b086d2ddc162971c9a4d44ecb9adb744d92556e1 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Mon, 24 Jul 2023 18:47:58 +0200 Subject: [PATCH 15/27] Reduce api calls and log spam --- plugins/plugins/core/components/ChatPage.js | 1170 ++++++++--------- .../plugins/core/components/ChatScroller.js | 485 +++---- .../core/components/UserInfo/UserInfo.js | 221 ++-- 3 files changed, 905 insertions(+), 971 deletions(-) diff --git a/plugins/plugins/core/components/ChatPage.js b/plugins/plugins/core/components/ChatPage.js index 9cb100cd..c996d325 100644 --- a/plugins/plugins/core/components/ChatPage.js +++ b/plugins/plugins/core/components/ChatPage.js @@ -1,52 +1,56 @@ -import { LitElement, html, css } from 'lit'; -import { animate } from '@lit-labs/motion'; -import { Epml } from '../../../epml.js'; -import { use, get, translate, registerTranslateConfig } from 'lit-translate'; +import { LitElement, html, css } from 'lit' +import { animate } from '@lit-labs/motion' +import { Epml } from '../../../epml.js' +import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import { generateHTML } from '@tiptap/core' +import { unsafeHTML } from 'lit/directives/unsafe-html.js' +import { Editor, Extension } from '@tiptap/core' +import { escape } from 'html-escaper' +import { inputKeyCodes } from '../../utils/keyCodes.js' +import { replaceMessagesEdited } from '../../utils/replace-messages-edited.js' +import { publishData } from '../../utils/publish-image.js' +import { EmojiPicker } from 'emoji-picker-js' + +import * as zip from '@zip.js/zip.js' + +import localForage from 'localforage' import StarterKit from '@tiptap/starter-kit' -import Underline from '@tiptap/extension-underline'; +import Underline from '@tiptap/extension-underline' import Placeholder from '@tiptap/extension-placeholder' import Highlight from '@tiptap/extension-highlight' -import { unsafeHTML } from 'lit/directives/unsafe-html.js'; -import { Editor, Extension } from '@tiptap/core' -import * as zip from "@zip.js/zip.js"; -import './ChatGifs/ChatGifs.js'; +import WebWorker from 'web-worker:./computePowWorker.js' +import WebWorkerFile from 'web-worker:./computePowWorkerFile.js' +import ShortUniqueId from 'short-unique-id' +import Compressor from 'compressorjs' -import localForage from "localforage"; -registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) -}); -import ShortUniqueId from 'short-unique-id'; -import Compressor from 'compressorjs'; -import { escape } from 'html-escaper'; -import { inputKeyCodes } from '../../utils/keyCodes.js'; -import './ChatScroller.js'; -import './LevelFounder.js'; -import './NameMenu.js'; -import './TimeAgo.js'; -import './ChatTextEditor.js'; -import './WrapperModal.js'; -import './TipUser' +import './ChatScroller.js' +import './LevelFounder.js' +import './NameMenu.js' +import './TimeAgo.js' +import './ChatTextEditor.js' +import './WrapperModal.js' +import './TipUser.js' import './ChatSelect.js' import './ChatSideNavHeads.js' import './ChatLeaveGroup.js' import './ChatGroupSettings.js' import './ChatRightPanel.js' -import './ChatSeachResults.js'; -import '@polymer/paper-spinner/paper-spinner-lite.js'; -import '@material/mwc-button'; -import '@material/mwc-dialog'; -import '@material/mwc-icon'; -import { replaceMessagesEdited } from '../../utils/replace-messages-edited.js'; -import { publishData } from '../../utils/publish-image.js'; -import { EmojiPicker } from 'emoji-picker-js'; -import WebWorker from 'web-worker:./computePowWorker.js'; -import WebWorkerFile from 'web-worker:./computePowWorkerFile.js'; +import './ChatSeachResults.js' +import './ChatGifs/ChatGifs.js' + +import '@material/mwc-button' +import '@material/mwc-dialog' +import '@material/mwc-icon' import '@polymer/paper-dialog/paper-dialog.js' +import '@polymer/paper-spinner/paper-spinner-lite.js' + +registerTranslateConfig({ + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) +}) const chatLastSeen = localForage.createInstance({ name: "chat-last-seen", -}); +}) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -117,7 +121,7 @@ class ChatPage extends LitElement { } static get styles() { - return css` + return css` html { scroll-behavior: smooth; } @@ -308,10 +312,10 @@ class ChatPage extends LitElement { transform: scale(1.15); } - .chat-container { - display: grid; - max-height: 100%; - } + .chat-container { + display: grid; + max-height: 100%; + } .chat-text-area { display: flex; @@ -489,7 +493,7 @@ class ChatPage extends LitElement { 50% { opacity: 0.5; } -} + } .float-left { float: left; @@ -1319,7 +1323,7 @@ class ChatPage extends LitElement { showAnimation: false, position: 'top-start', boxShadow: 'rgba(4, 4, 5, 0.15) 0px 0px 0px 1px, rgba(0, 0, 0, 0.24) 0px 8px 16px 0px' - }); + }) this.openForwardOpen = false this.groupAdmin = [] this.groupMembers = [] @@ -1333,8 +1337,8 @@ class ChatPage extends LitElement { name: "", selected: false } - this.webWorker = null; - this.webWorkerFile = null; + this.webWorker = null + this.webWorkerFile = null this.currentEditor = '_chatEditorDOM' this.initialChat = this.initialChat.bind(this) this.setOpenGifModal = this.setOpenGifModal.bind(this) @@ -1348,27 +1352,26 @@ class ChatPage extends LitElement { } } - setOpenGifModal(value) { this.openGifModal = value } _toggle(value) { - this.shifted = value === (false || true) ? value : !this.shifted; + this.shifted = value === (false || true) ? value : !this.shifted this.requestUpdate() } setOpenTipUser(props) { - this.openTipUser = props; + this.openTipUser = props } setOpenUserInfo(props) { - this.openUserInfo = props; + this.openUserInfo = props } setUserName(props) { - this.userName = props.senderName ? props.senderName : props.sender; - this.setSelectedHead(props); + this.userName = props.senderName ? props.senderName : props.sender + this.setSelectedHead(props) } setSelectedHead(props) { @@ -1376,7 +1379,7 @@ class ChatPage extends LitElement { ...this.selectedHead, address: props.sender, name: props.senderName, - }; + } } toggleEnableChatEnter() { @@ -1389,11 +1392,9 @@ class ChatPage extends LitElement { } setGifsLoading(props) { - this.gifsLoading = props; + this.gifsLoading = props } - - render() { return html`
@@ -1459,7 +1460,6 @@ class ChatPage extends LitElement { this.shadowRoot.querySelector("chat-scroller").shadowRoot.getElementById("downObserver") .scrollIntoView({ behavior: 'smooth', - }); }}> @@ -1575,7 +1575,7 @@ class ChatPage extends LitElement { `: ''} { - this.removeImage(); + this.removeImage() }} style=${(this.imageFile && !this.isUploadingImage) ? "visibility:visible; z-index:50" : "visibility: hidden;z-index:-100"}>
@@ -1602,19 +1602,18 @@ class ChatPage extends LitElement {