mirror of
https://github.com/Qortal/qortal-ui.git
synced 2025-02-11 17:55:51 +00:00
commit
800884302d
@ -33,6 +33,11 @@ Base64Message.decode = function (string, keys, ref) {
|
|||||||
let hubString = ''
|
let hubString = ''
|
||||||
|
|
||||||
const res = decryptSingle(string, keys, false)
|
const res = decryptSingle(string, keys, false)
|
||||||
|
|
||||||
|
if (res === 'noKey' || res === 'decryptionFailed') {
|
||||||
|
return '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"This message could not be decrypted"}]}]},"images":[""],"repliedTo":"","version":3}'
|
||||||
|
}
|
||||||
|
|
||||||
const decryptToUnit8Array = base64ToUint8Array(res)
|
const decryptToUnit8Array = base64ToUint8Array(res)
|
||||||
const responseData = uint8ArrayToObject(decryptToUnit8Array)
|
const responseData = uint8ArrayToObject(decryptToUnit8Array)
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ export function base64ToUint8Array(base64) {
|
|||||||
export function uint8ArrayToBase64(uint8Array) {
|
export function uint8ArrayToBase64(uint8Array) {
|
||||||
const length = uint8Array.length
|
const length = uint8Array.length
|
||||||
let binaryString = ''
|
let binaryString = ''
|
||||||
const chunkSize = 1024 * 1024 // Process 1MB at a time
|
// Process 1MB at a time
|
||||||
|
const chunkSize = 1024 * 1024
|
||||||
|
|
||||||
for (let i = 0; i < length; i += chunkSize) {
|
for (let i = 0; i < length; i += chunkSize) {
|
||||||
const chunkEnd = Math.min(i + chunkSize, length)
|
const chunkEnd = Math.min(i + chunkSize, length)
|
||||||
@ -104,7 +105,8 @@ export function validateSecretKey(obj) {
|
|||||||
|
|
||||||
// Function to create a symmetric key and nonce
|
// Function to create a symmetric key and nonce
|
||||||
export const createSymmetricKeyAndNonce = () => {
|
export const createSymmetricKeyAndNonce = () => {
|
||||||
const messageKey = new Uint8Array(32) // 32 bytes for the symmetric key
|
// 32 bytes for the symmetric key
|
||||||
|
const messageKey = new Uint8Array(32)
|
||||||
crypto.getRandomValues(messageKey)
|
crypto.getRandomValues(messageKey)
|
||||||
|
|
||||||
return { messageKey: uint8ArrayToBase64(messageKey)}
|
return { messageKey: uint8ArrayToBase64(messageKey)}
|
||||||
@ -233,11 +235,13 @@ export const encryptSingle = async (data64, secretKeyObject, typeNumber = 2) =>
|
|||||||
encryptedDataBase64 = uint8ArrayToBase64(encryptedData)
|
encryptedDataBase64 = uint8ArrayToBase64(encryptedData)
|
||||||
|
|
||||||
// Concatenate the highest key, type number, and encrypted data (old format)
|
// Concatenate the highest key, type number, and encrypted data (old format)
|
||||||
const highestKeyStr = highestKey.toString().padStart(10, '0') // Fixed length of 10 digits
|
// Fixed length of 10 digits
|
||||||
|
const highestKeyStr = highestKey.toString().padStart(10, '0')
|
||||||
finalEncryptedData = btoa(highestKeyStr + encryptedDataBase64)
|
finalEncryptedData = btoa(highestKeyStr + encryptedDataBase64)
|
||||||
} else {
|
} else {
|
||||||
// New format: Generate a random nonce and embed it in the message
|
// New format: Generate a random nonce and embed it in the message
|
||||||
nonce = new Uint8Array(24) // 24 bytes for the nonce
|
// 24 bytes for the nonce
|
||||||
|
nonce = new Uint8Array(24)
|
||||||
crypto.getRandomValues(nonce)
|
crypto.getRandomValues(nonce)
|
||||||
|
|
||||||
// Encrypt the data with the new nonce and message key
|
// Encrypt the data with the new nonce and message key
|
||||||
@ -248,7 +252,8 @@ export const encryptSingle = async (data64, secretKeyObject, typeNumber = 2) =>
|
|||||||
const nonceBase64 = uint8ArrayToBase64(nonce)
|
const nonceBase64 = uint8ArrayToBase64(nonce)
|
||||||
|
|
||||||
// Concatenate the highest key, type number, nonce, and encrypted data (new format)
|
// Concatenate the highest key, type number, nonce, and encrypted data (new format)
|
||||||
const highestKeyStr = highestKey.toString().padStart(10, '0') // Fixed length of 10 digits
|
// Fixed length of 10 digits
|
||||||
|
const highestKeyStr = highestKey.toString().padStart(10, '0')
|
||||||
const highestKeyBytes = new TextEncoder().encode(highestKeyStr.padStart(10, '0'))
|
const highestKeyBytes = new TextEncoder().encode(highestKeyStr.padStart(10, '0'))
|
||||||
const typeNumberBytes = new TextEncoder().encode(typeNumberStr.padStart(3, '0'))
|
const typeNumberBytes = new TextEncoder().encode(typeNumberStr.padStart(3, '0'))
|
||||||
|
|
||||||
@ -306,7 +311,7 @@ export function decryptSingle(data64, secretKeyObject, skipDecodeBase64) {
|
|||||||
|
|
||||||
// Check if we have a valid secret key for the extracted highestKey
|
// Check if we have a valid secret key for the extracted highestKey
|
||||||
if (!secretKeyObject[highestKey]) {
|
if (!secretKeyObject[highestKey]) {
|
||||||
throw new Error('Cannot find correct secretKey')
|
return 'noKey'
|
||||||
}
|
}
|
||||||
|
|
||||||
const secretKeyEntry = secretKeyObject[highestKey]
|
const secretKeyEntry = secretKeyObject[highestKey]
|
||||||
@ -315,18 +320,24 @@ export function decryptSingle(data64, secretKeyObject, skipDecodeBase64) {
|
|||||||
|
|
||||||
// Determine if typeNumber exists by checking if the next 3 characters after keyStr are digits
|
// Determine if typeNumber exists by checking if the next 3 characters after keyStr are digits
|
||||||
const possibleTypeNumberStr = decodeForNumber.slice(10, 13)
|
const possibleTypeNumberStr = decodeForNumber.slice(10, 13)
|
||||||
const hasTypeNumber = /^\d{3}$/.test(possibleTypeNumberStr) // Check if next 3 characters are digits
|
|
||||||
|
// Check if next 3 characters are digits
|
||||||
|
const hasTypeNumber = /^\d{3}$/.test(possibleTypeNumberStr)
|
||||||
|
|
||||||
if (secretKeyEntry.nonce) {
|
if (secretKeyEntry.nonce) {
|
||||||
// Old format: nonce is present in the secretKeyObject, so no type number exists
|
// Old format: nonce is present in the secretKeyObject, so no type number exists
|
||||||
nonceBase64 = secretKeyEntry.nonce
|
nonceBase64 = secretKeyEntry.nonce
|
||||||
encryptedDataBase64 = decodeForNumber.slice(10) // The remaining part is the encrypted data
|
|
||||||
|
// The remaining part is the encrypted data
|
||||||
|
encryptedDataBase64 = decodeForNumber.slice(10)
|
||||||
} else {
|
} else {
|
||||||
if (hasTypeNumber) {
|
if (hasTypeNumber) {
|
||||||
// const typeNumberStr = new TextDecoder().decode(typeNumberBytes)
|
|
||||||
if(decodeForNumber.slice(10, 13) !== '001'){
|
if(decodeForNumber.slice(10, 13) !== '001'){
|
||||||
const decodedBinary = base64ToUint8Array(decodedData)
|
const decodedBinary = base64ToUint8Array(decodedData)
|
||||||
const highestKeyBytes = decodedBinary.slice(0, 10) // if ASCII digits only
|
|
||||||
|
// if ASCII digits only
|
||||||
|
const highestKeyBytes = decodedBinary.slice(0, 10)
|
||||||
|
|
||||||
const highestKeyStr = new TextDecoder().decode(highestKeyBytes)
|
const highestKeyStr = new TextDecoder().decode(highestKeyBytes)
|
||||||
const nonce = decodedBinary.slice(13, 13 + 24)
|
const nonce = decodedBinary.slice(13, 13 + 24)
|
||||||
const encryptedData = decodedBinary.slice(13 + 24)
|
const encryptedData = decodedBinary.slice(13 + 24)
|
||||||
@ -336,7 +347,7 @@ export function decryptSingle(data64, secretKeyObject, skipDecodeBase64) {
|
|||||||
|
|
||||||
// Check if decryption was successful
|
// Check if decryption was successful
|
||||||
if (!decryptedBytes) {
|
if (!decryptedBytes) {
|
||||||
throw new Error("Decryption failed")
|
return 'decryptionFailed'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the decrypted Uint8Array back to a Base64 string
|
// Convert the decrypted Uint8Array back to a Base64 string
|
||||||
@ -344,13 +355,21 @@ export function decryptSingle(data64, secretKeyObject, skipDecodeBase64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New format: Extract type number and nonce
|
// New format: Extract type number and nonce
|
||||||
typeNumberStr = possibleTypeNumberStr // Extract type number
|
// Extract type number
|
||||||
nonceBase64 = decodeForNumber.slice(13, 45) // Extract nonce (next 32 characters after type number)
|
typeNumberStr = possibleTypeNumberStr
|
||||||
encryptedDataBase64 = decodeForNumber.slice(45) // The remaining part is the encrypted data
|
|
||||||
|
// Extract nonce (next 32 characters after type number)
|
||||||
|
nonceBase64 = decodeForNumber.slice(13, 45)
|
||||||
|
|
||||||
|
// The remaining part is the encrypted data
|
||||||
|
encryptedDataBase64 = decodeForNumber.slice(45)
|
||||||
} else {
|
} else {
|
||||||
// Old format without type number (nonce is embedded in the message, first 32 characters after keyStr)
|
// Old format without type number (nonce is embedded in the message, first 32 characters after keyStr)
|
||||||
nonceBase64 = decodeForNumber.slice(10, 42) // First 32 characters for the nonce
|
// First 32 characters for the nonce
|
||||||
encryptedDataBase64 = decodeForNumber.slice(42) // The remaining part is the encrypted data
|
nonceBase64 = decodeForNumber.slice(10, 42)
|
||||||
|
|
||||||
|
// The remaining part is the encrypted data
|
||||||
|
encryptedDataBase64 = decodeForNumber.slice(42)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +379,7 @@ export function decryptSingle(data64, secretKeyObject, skipDecodeBase64) {
|
|||||||
const messageKey = base64ToUint8Array(secretKeyEntry.messageKey)
|
const messageKey = base64ToUint8Array(secretKeyEntry.messageKey)
|
||||||
|
|
||||||
if (!(Uint8ArrayData instanceof Uint8Array)) {
|
if (!(Uint8ArrayData instanceof Uint8Array)) {
|
||||||
throw new Error("The Uint8ArrayData you've submitted is invalid")
|
return 'decryptionFailed'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt the data using the nonce and messageKey
|
// Decrypt the data using the nonce and messageKey
|
||||||
@ -368,7 +387,7 @@ export function decryptSingle(data64, secretKeyObject, skipDecodeBase64) {
|
|||||||
|
|
||||||
// Check if decryption was successful
|
// Check if decryption was successful
|
||||||
if (!decryptedData) {
|
if (!decryptedData) {
|
||||||
throw new Error("Decryption failed")
|
return 'decryptionFailed'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the decrypted Uint8Array back to a Base64 string
|
// Convert the decrypted Uint8Array back to a Base64 string
|
||||||
@ -383,25 +402,33 @@ export const decryptGroupEncryptionWithSharingKey = async (data64EncryptedData,
|
|||||||
|
|
||||||
// Extract the nonce
|
// Extract the nonce
|
||||||
const nonceStartPosition = strUint8Array.length
|
const nonceStartPosition = strUint8Array.length
|
||||||
const nonceEndPosition = nonceStartPosition + 24 // Nonce is 24 bytes
|
|
||||||
|
// Nonce is 24 bytes
|
||||||
|
const nonceEndPosition = nonceStartPosition + 24
|
||||||
const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition)
|
const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition)
|
||||||
|
|
||||||
// Extract the shared keyNonce
|
// Extract the shared keyNonce
|
||||||
const keyNonceStartPosition = nonceEndPosition
|
const keyNonceStartPosition = nonceEndPosition
|
||||||
const keyNonceEndPosition = keyNonceStartPosition + 24 // Nonce is 24 bytes
|
|
||||||
|
// Nonce is 24 bytes
|
||||||
|
const keyNonceEndPosition = keyNonceStartPosition + 24
|
||||||
const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition)
|
const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition)
|
||||||
|
|
||||||
// Extract the sender's public key
|
// Extract the sender's public key
|
||||||
const senderPublicKeyStartPosition = keyNonceEndPosition
|
const senderPublicKeyStartPosition = keyNonceEndPosition
|
||||||
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32 // Public keys are 32 bytes
|
|
||||||
|
// Public keys are 32 bytes
|
||||||
|
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32
|
||||||
|
|
||||||
// Calculate count first
|
// Calculate count first
|
||||||
const countStartPosition = allCombined.length - 4 // 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
// 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
||||||
|
const countStartPosition = allCombined.length - 4
|
||||||
const countArray = allCombined.slice(countStartPosition, countStartPosition + 4)
|
const countArray = allCombined.slice(countStartPosition, countStartPosition + 4)
|
||||||
const count = new Uint32Array(countArray.buffer)[0]
|
const count = new Uint32Array(countArray.buffer)[0]
|
||||||
|
|
||||||
// Then use count to calculate encryptedData
|
// Then use count to calculate encryptedData
|
||||||
const encryptedDataStartPosition = senderPublicKeyEndPosition // start position of encryptedData
|
// start position of encryptedData
|
||||||
|
const encryptedDataStartPosition = senderPublicKeyEndPosition
|
||||||
const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4)
|
const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4)
|
||||||
const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition)
|
const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition)
|
||||||
const symmetricKey = base64ToUint8Array(key)
|
const symmetricKey = base64ToUint8Array(key)
|
||||||
@ -426,26 +453,34 @@ export function decryptGroupDataQortalRequest(data64EncryptedData, privateKey) {
|
|||||||
|
|
||||||
// Extract the nonce
|
// Extract the nonce
|
||||||
const nonceStartPosition = strUint8Array.length
|
const nonceStartPosition = strUint8Array.length
|
||||||
const nonceEndPosition = nonceStartPosition + 24 // Nonce is 24 bytes
|
|
||||||
|
// Nonce is 24 bytes
|
||||||
|
const nonceEndPosition = nonceStartPosition + 24
|
||||||
const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition)
|
const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition)
|
||||||
|
|
||||||
// Extract the shared keyNonce
|
// Extract the shared keyNonce
|
||||||
const keyNonceStartPosition = nonceEndPosition
|
const keyNonceStartPosition = nonceEndPosition
|
||||||
const keyNonceEndPosition = keyNonceStartPosition + 24 // Nonce is 24 bytes
|
|
||||||
|
// Nonce is 24 bytes
|
||||||
|
const keyNonceEndPosition = keyNonceStartPosition + 24
|
||||||
const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition)
|
const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition)
|
||||||
|
|
||||||
// Extract the sender's public key
|
// Extract the sender's public key
|
||||||
const senderPublicKeyStartPosition = keyNonceEndPosition
|
const senderPublicKeyStartPosition = keyNonceEndPosition
|
||||||
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32 // Public keys are 32 bytes
|
|
||||||
|
// Public keys are 32 bytes
|
||||||
|
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32
|
||||||
const senderPublicKey = allCombined.slice(senderPublicKeyStartPosition, senderPublicKeyEndPosition)
|
const senderPublicKey = allCombined.slice(senderPublicKeyStartPosition, senderPublicKeyEndPosition)
|
||||||
|
|
||||||
// Calculate count first
|
// Calculate count first
|
||||||
const countStartPosition = allCombined.length - 4 // 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
// 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
||||||
|
const countStartPosition = allCombined.length - 4
|
||||||
const countArray = allCombined.slice(countStartPosition, countStartPosition + 4)
|
const countArray = allCombined.slice(countStartPosition, countStartPosition + 4)
|
||||||
const count = new Uint32Array(countArray.buffer)[0]
|
const count = new Uint32Array(countArray.buffer)[0]
|
||||||
|
|
||||||
// Then use count to calculate encryptedData
|
// Then use count to calculate encryptedData
|
||||||
const encryptedDataStartPosition = senderPublicKeyEndPosition // start position of encryptedData
|
// start position of encryptedData
|
||||||
|
const encryptedDataStartPosition = senderPublicKeyEndPosition
|
||||||
const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4)
|
const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4)
|
||||||
const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition)
|
const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition)
|
||||||
|
|
||||||
@ -474,6 +509,7 @@ export function decryptGroupDataQortalRequest(data64EncryptedData, privateKey) {
|
|||||||
if (decryptedKey) {
|
if (decryptedKey) {
|
||||||
// Decrypt the data using the symmetric key.
|
// Decrypt the data using the symmetric key.
|
||||||
const decryptedData = nacl.secretbox.open(encryptedData, nonce, decryptedKey)
|
const decryptedData = nacl.secretbox.open(encryptedData, nonce, decryptedKey)
|
||||||
|
|
||||||
// If decryption was successful, decryptedData will not be null.
|
// If decryption was successful, decryptedData will not be null.
|
||||||
if (decryptedData) {
|
if (decryptedData) {
|
||||||
return decryptedData
|
return decryptedData
|
||||||
@ -493,26 +529,34 @@ export function decryptGroupData(data64EncryptedData, privateKey) {
|
|||||||
|
|
||||||
// Extract the nonce
|
// Extract the nonce
|
||||||
const nonceStartPosition = strUint8Array.length
|
const nonceStartPosition = strUint8Array.length
|
||||||
const nonceEndPosition = nonceStartPosition + 24 // Nonce is 24 bytes
|
|
||||||
|
// Nonce is 24 bytes
|
||||||
|
const nonceEndPosition = nonceStartPosition + 24
|
||||||
const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition)
|
const nonce = allCombined.slice(nonceStartPosition, nonceEndPosition)
|
||||||
|
|
||||||
// Extract the shared keyNonce
|
// Extract the shared keyNonce
|
||||||
const keyNonceStartPosition = nonceEndPosition
|
const keyNonceStartPosition = nonceEndPosition
|
||||||
const keyNonceEndPosition = keyNonceStartPosition + 24 // Nonce is 24 bytes
|
|
||||||
|
// Nonce is 24 bytes
|
||||||
|
const keyNonceEndPosition = keyNonceStartPosition + 24
|
||||||
const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition)
|
const keyNonce = allCombined.slice(keyNonceStartPosition, keyNonceEndPosition)
|
||||||
|
|
||||||
// Extract the sender's public key
|
// Extract the sender's public key
|
||||||
const senderPublicKeyStartPosition = keyNonceEndPosition
|
const senderPublicKeyStartPosition = keyNonceEndPosition
|
||||||
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32 // Public keys are 32 bytes
|
|
||||||
|
// Public keys are 32 bytes
|
||||||
|
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32
|
||||||
const senderPublicKey = allCombined.slice(senderPublicKeyStartPosition, senderPublicKeyEndPosition)
|
const senderPublicKey = allCombined.slice(senderPublicKeyStartPosition, senderPublicKeyEndPosition)
|
||||||
|
|
||||||
// Calculate count first
|
// Calculate count first
|
||||||
const countStartPosition = allCombined.length - 4 // 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
// 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
||||||
|
const countStartPosition = allCombined.length - 4
|
||||||
const countArray = allCombined.slice(countStartPosition, countStartPosition + 4)
|
const countArray = allCombined.slice(countStartPosition, countStartPosition + 4)
|
||||||
const count = new Uint32Array(countArray.buffer)[0]
|
const count = new Uint32Array(countArray.buffer)[0]
|
||||||
|
|
||||||
// Then use count to calculate encryptedData
|
// Then use count to calculate encryptedData
|
||||||
const encryptedDataStartPosition = senderPublicKeyEndPosition // start position of encryptedData
|
// start position of encryptedData
|
||||||
|
const encryptedDataStartPosition = senderPublicKeyEndPosition
|
||||||
const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4)
|
const encryptedDataEndPosition = allCombined.length - ((count * (32 + 16)) + 4)
|
||||||
const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition)
|
const encryptedData = allCombined.slice(encryptedDataStartPosition, encryptedDataEndPosition)
|
||||||
|
|
||||||
|
@ -114,3 +114,6 @@ export const OPEN_PROFILE = 'OPEN_PROFILE'
|
|||||||
|
|
||||||
// ADMIN_ACTION
|
// ADMIN_ACTION
|
||||||
export const ADMIN_ACTION = 'ADMIN_ACTION'
|
export const ADMIN_ACTION = 'ADMIN_ACTION'
|
||||||
|
|
||||||
|
// SIGN_TRANSACTION
|
||||||
|
export const SIGN_TRANSACTION = 'SIGN_TRANSACTION'
|
||||||
|
@ -2789,6 +2789,11 @@ const decode = (string, keys, ref) => {
|
|||||||
let hubString = ''
|
let hubString = ''
|
||||||
|
|
||||||
const res = decryptSingle(string, keys, false)
|
const res = decryptSingle(string, keys, false)
|
||||||
|
|
||||||
|
if (res === 'noKey' || res === 'decryptionFailed') {
|
||||||
|
return '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"This message could not be decrypted"}]}]},"images":[""],"repliedTo":"","version":3}'
|
||||||
|
}
|
||||||
|
|
||||||
const decryptToUnit8Array = base64ToUint8Array(res)
|
const decryptToUnit8Array = base64ToUint8Array(res)
|
||||||
const responseData = uint8ArrayToObject(decryptToUnit8Array)
|
const responseData = uint8ArrayToObject(decryptToUnit8Array)
|
||||||
|
|
||||||
|
@ -2866,14 +2866,20 @@ class GroupManagement extends LitElement {
|
|||||||
|
|
||||||
let data
|
let data
|
||||||
let supArray = []
|
let supArray = []
|
||||||
|
let allSymKeys = []
|
||||||
let gAdmin = ''
|
let gAdmin = ''
|
||||||
let gAddress = ''
|
let gAddress = ''
|
||||||
|
let keysToOld = "Wait until an admin re-encrypts the keys. Only unencrypted messages will be displayed."
|
||||||
|
let retryDownload = "Retry downloading and decrypt keys in 5 seconds! Please wait..."
|
||||||
|
let failDownload = "Error downloading and decrypt keys! Only unencrypted messages will be displayed. Please try again later..."
|
||||||
|
let all_ok = false
|
||||||
|
let counter = 0
|
||||||
|
|
||||||
const symIdentifier = 'symmetric-qchat-group-' + groupId
|
const symIdentifier = 'symmetric-qchat-group-' + groupId
|
||||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
const getNameUrl = `${nodeUrl}/arbitrary/resources?service=DOCUMENT_PRIVATE&identifier=${symIdentifier}&limit=1&reverse=true`
|
const getNameUrl = `${nodeUrl}/arbitrary/resources?service=DOCUMENT_PRIVATE&identifier=${symIdentifier}&limit=0&reverse=true`
|
||||||
const getAdminUrl = `${nodeUrl}/groups/members/${groupId}?onlyAdmins=true&limit=20`
|
const getAdminUrl = `${nodeUrl}/groups/members/${groupId}?onlyAdmins=true&limit=0`
|
||||||
|
|
||||||
supArray = await fetch(getNameUrl).then(response => {
|
supArray = await fetch(getNameUrl).then(response => {
|
||||||
return response.json()
|
return response.json()
|
||||||
@ -2882,10 +2888,21 @@ class GroupManagement extends LitElement {
|
|||||||
if (this.isEmptyArray(supArray) || groupId === 0) {
|
if (this.isEmptyArray(supArray) || groupId === 0) {
|
||||||
console.log("No Symetric Key")
|
console.log("No Symetric Key")
|
||||||
} else {
|
} else {
|
||||||
supArray.map(item => {
|
supArray.forEach(item => {
|
||||||
gAdmin = item.name
|
const symInfoObj = {
|
||||||
|
name: item.name,
|
||||||
|
identifier: item.identifier,
|
||||||
|
timestamp: item.updated ? item.updated : item.created
|
||||||
|
}
|
||||||
|
allSymKeys.push(symInfoObj)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let allSymKeysSorted = allSymKeys.sort(function(a, b) {
|
||||||
|
return b.timestamp - a.timestamp
|
||||||
|
})
|
||||||
|
|
||||||
|
gAdmin = allSymKeysSorted[0].name
|
||||||
|
|
||||||
const addressUrl = `${nodeUrl}/names/${gAdmin}`
|
const addressUrl = `${nodeUrl}/names/${gAdmin}`
|
||||||
|
|
||||||
let addressObject = await fetch(addressUrl).then(response => {
|
let addressObject = await fetch(addressUrl).then(response => {
|
||||||
@ -2907,20 +2924,41 @@ class GroupManagement extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (adminExists(gAddress)) {
|
if (adminExists(gAddress)) {
|
||||||
|
const sleep = (t) => new Promise(r => setTimeout(r, t))
|
||||||
const dataUrl = `${nodeUrl}/arbitrary/DOCUMENT_PRIVATE/${gAdmin}/${symIdentifier}?encoding=base64&rebuild=true&async=true`
|
const dataUrl = `${nodeUrl}/arbitrary/DOCUMENT_PRIVATE/${gAdmin}/${symIdentifier}?encoding=base64&rebuild=true&async=true`
|
||||||
const res = await fetch(dataUrl)
|
const res = await fetch(dataUrl)
|
||||||
|
|
||||||
data = await res.text()
|
do {
|
||||||
|
counter++
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
parentEpml.request('showSnackBar', `${retryDownload}`)
|
||||||
|
await sleep(5000)
|
||||||
|
} else {
|
||||||
|
data = await res.text()
|
||||||
|
all_ok = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter > 10) {
|
||||||
|
parentEpml.request('showSnackBar', `${failDownload}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} while (!all_ok)
|
||||||
|
|
||||||
const decryptedKey = await this.decryptGroupEncryption(data)
|
const decryptedKey = await this.decryptGroupEncryption(data)
|
||||||
const dataint8Array = base64ToUint8Array(decryptedKey.data)
|
|
||||||
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array)
|
|
||||||
|
|
||||||
if (!validateSecretKey(decryptedKeyToObject)) {
|
if (decryptedKey === undefined) {
|
||||||
throw new Error("SecretKey is not valid")
|
parentEpml.request('showSnackBar', `${keysToOld}`)
|
||||||
|
} else {
|
||||||
|
const dataint8Array = base64ToUint8Array(decryptedKey.data)
|
||||||
|
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array)
|
||||||
|
|
||||||
|
if (!validateSecretKey(decryptedKeyToObject)) {
|
||||||
|
throw new Error("SecretKey is not valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
this.secretKeys = decryptedKeyToObject
|
||||||
}
|
}
|
||||||
|
|
||||||
this.secretKeys = decryptedKeyToObject
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2997,6 +3035,11 @@ class GroupManagement extends LitElement {
|
|||||||
let hubString = ''
|
let hubString = ''
|
||||||
|
|
||||||
const res = decryptSingle(string, this.secretKeys, false)
|
const res = decryptSingle(string, this.secretKeys, false)
|
||||||
|
|
||||||
|
if (res === 'noKey' || res === 'decryptionFailed') {
|
||||||
|
return '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"This message could not be decrypted"}]}]},"images":[""],"repliedTo":"","version":3}'
|
||||||
|
}
|
||||||
|
|
||||||
const decryptToUnit8Array = base64ToUint8Array(res)
|
const decryptToUnit8Array = base64ToUint8Array(res)
|
||||||
const responseData = uint8ArrayToObject(decryptToUnit8Array)
|
const responseData = uint8ArrayToObject(decryptToUnit8Array)
|
||||||
|
|
||||||
@ -3080,7 +3123,7 @@ class GroupManagement extends LitElement {
|
|||||||
let getEditedArray = await parentEpml.request('apiCall', {
|
let getEditedArray = await parentEpml.request('apiCall', {
|
||||||
url: `/chat/messages?txGroupId=${involved}&haschatreference=true&encoding=BASE64&limit=0&reverse=false`
|
url: `/chat/messages?txGroupId=${involved}&haschatreference=true&encoding=BASE64&limit=0&reverse=false`
|
||||||
})
|
})
|
||||||
|
|
||||||
chaEditedArray = getEditedArray
|
chaEditedArray = getEditedArray
|
||||||
|
|
||||||
// Replace messages which got edited in the chatMessageArray
|
// Replace messages which got edited in the chatMessageArray
|
||||||
@ -3143,7 +3186,7 @@ class GroupManagement extends LitElement {
|
|||||||
if (this.shadowRoot.getElementById('chat-container').innerHTML === '') {
|
if (this.shadowRoot.getElementById('chat-container').innerHTML === '') {
|
||||||
this.shadowRoot.getElementById('chat-container').innerHTML = ''
|
this.shadowRoot.getElementById('chat-container').innerHTML = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isEmptyArray(renderArray)) {
|
if (this.isEmptyArray(renderArray)) {
|
||||||
const chatEmpty = document.createElement('div')
|
const chatEmpty = document.createElement('div')
|
||||||
chatEmpty.classList.add('no-messages')
|
chatEmpty.classList.add('no-messages')
|
||||||
@ -5778,4 +5821,4 @@ class GroupManagement extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('group-management', GroupManagement)
|
window.customElements.define('group-management', GroupManagement)
|
||||||
|
@ -447,17 +447,22 @@ class Chat extends LitElement {
|
|||||||
|
|
||||||
let data
|
let data
|
||||||
let supArray = []
|
let supArray = []
|
||||||
|
let allSymKeys = []
|
||||||
let gAdmin = ''
|
let gAdmin = ''
|
||||||
let gAddress = ''
|
let gAddress = ''
|
||||||
let currentGroupId = url.substring(6)
|
let currentGroupId = url.substring(6)
|
||||||
let symIdentifier = 'symmetric-qchat-group-' + currentGroupId
|
let symIdentifier = 'symmetric-qchat-group-' + currentGroupId
|
||||||
let locateString = "Downloading and decrypt keys ! Please wait..."
|
let locateString = "Downloading and decrypt keys! Please wait..."
|
||||||
let keysToOld = "Wait until an admin re-encrypts the keys. Only unencrypted messages will be displayed."
|
let keysToOld = "Wait until an admin re-encrypts the keys. Only unencrypted messages will be displayed."
|
||||||
|
let retryDownload = "Retry downloading and decrypt keys in 5 seconds! Please wait..."
|
||||||
|
let failDownload = "Error downloading and decrypt keys! Only unencrypted messages will be displayed. Please try again later..."
|
||||||
|
let all_ok = false
|
||||||
|
let counter = 0
|
||||||
|
|
||||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
const getNameUrl = `${nodeUrl}/arbitrary/resources?service=DOCUMENT_PRIVATE&identifier=${symIdentifier}&limit=1&reverse=true`
|
const getNameUrl = `${nodeUrl}/arbitrary/resources?service=DOCUMENT_PRIVATE&identifier=${symIdentifier}&limit=0&reverse=true`
|
||||||
const getAdminUrl = `${nodeUrl}/groups/members/${currentGroupId}?onlyAdmins=true&limit=20`
|
const getAdminUrl = `${nodeUrl}/groups/members/${currentGroupId}?onlyAdmins=true&limit=0`
|
||||||
|
|
||||||
if (localStorage.getItem("symKeysCurrent") === null) {
|
if (localStorage.getItem("symKeysCurrent") === null) {
|
||||||
localStorage.setItem("symKeysCurrent", "")
|
localStorage.setItem("symKeysCurrent", "")
|
||||||
@ -473,10 +478,21 @@ class Chat extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
parentEpml.request('showSnackBar', `${locateString}`)
|
parentEpml.request('showSnackBar', `${locateString}`)
|
||||||
|
|
||||||
supArray.map(item => {
|
supArray.forEach(item => {
|
||||||
gAdmin = item.name
|
const symInfoObj = {
|
||||||
|
name: item.name,
|
||||||
|
identifier: item.identifier,
|
||||||
|
timestamp: item.updated ? item.updated : item.created
|
||||||
|
}
|
||||||
|
allSymKeys.push(symInfoObj)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let allSymKeysSorted = allSymKeys.sort(function(a, b) {
|
||||||
|
return b.timestamp - a.timestamp
|
||||||
|
})
|
||||||
|
|
||||||
|
gAdmin = allSymKeysSorted[0].name
|
||||||
|
|
||||||
const addressUrl = `${nodeUrl}/names/${gAdmin}`
|
const addressUrl = `${nodeUrl}/names/${gAdmin}`
|
||||||
|
|
||||||
let addressObject = await fetch(addressUrl).then(response => {
|
let addressObject = await fetch(addressUrl).then(response => {
|
||||||
@ -498,10 +514,28 @@ class Chat extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (adminExists(gAddress)) {
|
if (adminExists(gAddress)) {
|
||||||
const dataUrl = `${nodeUrl}/arbitrary/DOCUMENT_PRIVATE/${gAdmin}/${symIdentifier}?encoding=base64&rebuild=true&async=true`
|
const sleep = (t) => new Promise(r => setTimeout(r, t))
|
||||||
|
const dataUrl = `${nodeUrl}/arbitrary/DOCUMENT_PRIVATE/${gAdmin}/${symIdentifier}?encoding=base64`
|
||||||
const res = await fetch(dataUrl)
|
const res = await fetch(dataUrl)
|
||||||
|
|
||||||
data = await res.text()
|
do {
|
||||||
|
counter++
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
parentEpml.request('showSnackBar', `${retryDownload}`)
|
||||||
|
await sleep(5000)
|
||||||
|
} else {
|
||||||
|
data = await res.text()
|
||||||
|
all_ok = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter > 10) {
|
||||||
|
parentEpml.request('showSnackBar', `${failDownload}`)
|
||||||
|
this.activeChatHeadUrl = url
|
||||||
|
this.requestUpdate()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} while (!all_ok)
|
||||||
|
|
||||||
const decryptedKey = await this.decryptGroupEncryption(data)
|
const decryptedKey = await this.decryptGroupEncryption(data)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
uint8ArrayStartsWith,
|
uint8ArrayStartsWith,
|
||||||
uint8ArrayToBase64
|
uint8ArrayToBase64
|
||||||
} from '../../components/qdn-action-encryption'
|
} from '../../components/qdn-action-encryption'
|
||||||
|
import { processTransactionVersion2 } from '../../../../../crypto/api/createTransaction'
|
||||||
import { webBrowserStyles, webBrowserModalStyles } from '../../components/plugins-css'
|
import { webBrowserStyles, webBrowserModalStyles } from '../../components/plugins-css'
|
||||||
import * as actions from '../../components/qdn-action-types'
|
import * as actions from '../../components/qdn-action-types'
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
@ -19,6 +20,8 @@ import ShortUniqueId from 'short-unique-id'
|
|||||||
import FileSaver from 'file-saver'
|
import FileSaver from 'file-saver'
|
||||||
import WebWorker from 'web-worker:./computePowWorkerFile.js'
|
import WebWorker from 'web-worker:./computePowWorkerFile.js'
|
||||||
import WebWorkerChat from 'web-worker:./computePowWorker.js'
|
import WebWorkerChat from 'web-worker:./computePowWorker.js'
|
||||||
|
import Base58 from '../../../../../crypto/api/deps/Base58'
|
||||||
|
import nacl from '../../../../../crypto/api/deps/nacl-fast'
|
||||||
import '@material/mwc-button'
|
import '@material/mwc-button'
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
import '@material/mwc-checkbox'
|
import '@material/mwc-checkbox'
|
||||||
@ -84,7 +87,7 @@ class WebBrowser extends LitElement {
|
|||||||
this.loader = new Loader()
|
this.loader = new Loader()
|
||||||
|
|
||||||
// Build initial display URL
|
// Build initial display URL
|
||||||
let displayUrl = ''
|
let displayUrl
|
||||||
|
|
||||||
if (this.dev === 'FRAMEWORK') {
|
if (this.dev === 'FRAMEWORK') {
|
||||||
displayUrl = 'qortal://app/development'
|
displayUrl = 'qortal://app/development'
|
||||||
@ -2271,6 +2274,140 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case actions.SIGN_TRANSACTION: {
|
||||||
|
const signNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
|
const signUrl = signNode.protocol + '://' + signNode.domain + ':' + signNode.port
|
||||||
|
const requiredFields = ['unsignedBytes']
|
||||||
|
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 shouldProcess = data.process || false
|
||||||
|
|
||||||
|
let url = `${signUrl}/transactions/decode?ignoreValidityChecks=false`
|
||||||
|
let body = data.unsignedBytes
|
||||||
|
|
||||||
|
const resp = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: body
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!resp.ok) {
|
||||||
|
const errorMsg = "Failed to decode transaction"
|
||||||
|
let data = {}
|
||||||
|
data['error'] = errorMsg
|
||||||
|
response = JSON.stringify(data)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
const decodedData = await resp.json()
|
||||||
|
|
||||||
|
const signRequest = await showModalAndWait(
|
||||||
|
actions.SIGN_TRANSACTION,
|
||||||
|
{
|
||||||
|
text1: `Do you give this application permission to ${ shouldProcess ? 'SIGN and PROCESS' : 'SIGN' } a transaction?`,
|
||||||
|
text2: "Read the transaction carefully before accepting!",
|
||||||
|
text3: `Tx type: ${decodedData.type}`,
|
||||||
|
json: decodedData
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (signRequest.action === 'accept') {
|
||||||
|
let urlConverted = `${signUrl}/transactions/convert`
|
||||||
|
|
||||||
|
const responseConverted = await fetch(urlConverted, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: data.unsignedBytes
|
||||||
|
})
|
||||||
|
|
||||||
|
const uint8PrivateKey = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey)
|
||||||
|
const uint8PublicKey = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.publicKey)
|
||||||
|
|
||||||
|
const keyPair = {
|
||||||
|
privateKey: uint8PrivateKey,
|
||||||
|
publicKey: uint8PublicKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
const convertedBytes = await responseConverted.text()
|
||||||
|
const txBytes = Base58.decode(data.unsignedBytes)
|
||||||
|
|
||||||
|
const _arbitraryBytesBuffer = Object.keys(txBytes).map(function (key) {
|
||||||
|
return txBytes[key]
|
||||||
|
})
|
||||||
|
|
||||||
|
const arbitraryBytesBuffer = new Uint8Array(_arbitraryBytesBuffer)
|
||||||
|
const txByteSigned = Base58.decode(convertedBytes)
|
||||||
|
|
||||||
|
const _bytesForSigningBuffer = Object.keys(txByteSigned).map(function (key) {
|
||||||
|
return txByteSigned[key]
|
||||||
|
})
|
||||||
|
|
||||||
|
const bytesForSigningBuffer = new Uint8Array(_bytesForSigningBuffer)
|
||||||
|
|
||||||
|
const signature = nacl.sign.detached(
|
||||||
|
bytesForSigningBuffer,
|
||||||
|
keyPair.privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
const signedBytes = utils.appendBuffer(arbitraryBytesBuffer, signature)
|
||||||
|
const signedBytesToBase58 = Base58.encode(signedBytes)
|
||||||
|
|
||||||
|
if(!shouldProcess) {
|
||||||
|
const errorMsg = "Process transaction was not requested! Signed bytes are: " + signedBytesToBase58
|
||||||
|
let data = {}
|
||||||
|
data['error'] = errorMsg
|
||||||
|
response = JSON.stringify(data)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.loader.show()
|
||||||
|
|
||||||
|
const res = await processTransactionVersion2(signedBytesToBase58)
|
||||||
|
|
||||||
|
if (!res.signature) {
|
||||||
|
const errorMsg = "Transaction was not able to be processed" + res.message
|
||||||
|
let data = {}
|
||||||
|
data['error'] = errorMsg
|
||||||
|
response = JSON.stringify(data)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
response = JSON.stringify(res)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
const data = {}
|
||||||
|
data['error'] = error.message || get("browserpage.bchange21")
|
||||||
|
response = JSON.stringify(data)
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
this.loader.hide()
|
||||||
|
}
|
||||||
|
} else if (signRequest.action === 'reject') {
|
||||||
|
response = '{"error": "User declined request"}'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
case actions.SEND_COIN: {
|
case actions.SEND_COIN: {
|
||||||
const requiredFields = ['coin', 'destinationAddress', 'amount']
|
const requiredFields = ['coin', 'destinationAddress', 'amount']
|
||||||
const missingFields = []
|
const missingFields = []
|
||||||
@ -2356,7 +2493,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (processPayment.action === 'reject') {
|
if (processPayment.action === 'reject') {
|
||||||
let errorMsg = "User declined request"
|
|
||||||
let myMsg1 = get("transactions.declined")
|
let myMsg1 = get("transactions.declined")
|
||||||
let myMsg2 = get("walletpage.wchange44")
|
let myMsg2 = get("walletpage.wchange44")
|
||||||
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
||||||
@ -2516,7 +2652,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (processPayment.action === 'reject') {
|
if (processPayment.action === 'reject') {
|
||||||
let errorMsg = "User declined request"
|
|
||||||
let myMsg1 = get("transactions.declined")
|
let myMsg1 = get("transactions.declined")
|
||||||
let myMsg2 = get("walletpage.wchange44")
|
let myMsg2 = get("walletpage.wchange44")
|
||||||
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
||||||
@ -2614,7 +2749,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (processPayment.action === 'reject') {
|
if (processPayment.action === 'reject') {
|
||||||
let errorMsg = "User declined request"
|
|
||||||
let myMsg1 = get("transactions.declined")
|
let myMsg1 = get("transactions.declined")
|
||||||
let myMsg2 = get("walletpage.wchange44")
|
let myMsg2 = get("walletpage.wchange44")
|
||||||
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
||||||
@ -2712,7 +2846,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (processPayment.action === 'reject') {
|
if (processPayment.action === 'reject') {
|
||||||
let errorMsg = "User declined request"
|
|
||||||
let myMsg1 = get("transactions.declined")
|
let myMsg1 = get("transactions.declined")
|
||||||
let myMsg2 = get("walletpage.wchange44")
|
let myMsg2 = get("walletpage.wchange44")
|
||||||
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
||||||
@ -2810,7 +2943,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (processPayment.action === 'reject') {
|
if (processPayment.action === 'reject') {
|
||||||
let errorMsg = "User declined request"
|
|
||||||
let myMsg1 = get("transactions.declined")
|
let myMsg1 = get("transactions.declined")
|
||||||
let myMsg2 = get("walletpage.wchange44")
|
let myMsg2 = get("walletpage.wchange44")
|
||||||
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
||||||
@ -2908,7 +3040,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (processPayment.action === 'reject') {
|
if (processPayment.action === 'reject') {
|
||||||
let errorMsg = "User declined request"
|
|
||||||
let myMsg1 = get("transactions.declined")
|
let myMsg1 = get("transactions.declined")
|
||||||
let myMsg2 = get("walletpage.wchange44")
|
let myMsg2 = get("walletpage.wchange44")
|
||||||
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
||||||
@ -3006,7 +3137,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (processPayment.action === 'reject') {
|
if (processPayment.action === 'reject') {
|
||||||
let errorMsg = "User declined request"
|
|
||||||
let myMsg1 = get("transactions.declined")
|
let myMsg1 = get("transactions.declined")
|
||||||
let myMsg2 = get("walletpage.wchange44")
|
let myMsg2 = get("walletpage.wchange44")
|
||||||
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
await showErrorAndWait("DECLINED_REQUEST", myMsg1, myMsg2)
|
||||||
@ -4032,6 +4162,13 @@ async function showModalAndWait(type, data) {
|
|||||||
<p class="modal-paragraph">${get("browserpage.bchange22")}</p>
|
<p class="modal-paragraph">${get("browserpage.bchange22")}</p>
|
||||||
<p class="modal-paragraph">${get("chatpage.cchange4")}: <span> ${data.message}</span></p>
|
<p class="modal-paragraph">${get("chatpage.cchange4")}: <span> ${data.message}</span></p>
|
||||||
` : ''}
|
` : ''}
|
||||||
|
|
||||||
|
${type === actions.SIGN_TRANSACTION ? `
|
||||||
|
<p class="modal-paragraph">${data.text1}</p>
|
||||||
|
<p class="modal-paragraph">${data.text2}</p>
|
||||||
|
<p class="modal-paragraph">${data.text3}</p>
|
||||||
|
<p class="modal-paragraph">Transaction: <span>${data.json}</span></p>
|
||||||
|
` : ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-buttons">
|
<div class="modal-buttons">
|
||||||
<button id="cancel-button">${get("browserpage.bchange27")}</button>
|
<button id="cancel-button">${get("browserpage.bchange27")}</button>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user