diff --git a/crypto/api/deps/Base64Message.js b/crypto/api/deps/Base64Message.js index 27d5822f..f74c282f 100644 --- a/crypto/api/deps/Base64Message.js +++ b/crypto/api/deps/Base64Message.js @@ -4,6 +4,12 @@ import { uint8ArrayToObject, decryptSingle } from '../../../plugins/plugins/core/components/GroupEncryption.js' +import { + extensionToPointer, + encodedToChar, + embedToString, + parseQortalLink +} from '../../../plugins/plugins/core/components/qdn-action-constants.js' const Base64Message = {} @@ -29,13 +35,16 @@ Base64Message.decode = function (string, keys, ref) { } } else { let repliedToStr = '' + let addedFileStr = '' let messageStr = '' let hubString = '' + let messageRep = '' + let messageUseEmbed = {} 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}' + return '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"This message could not be decrypted"}]}]}' + addedFileStr + ',"repliedTo":"","version":3,"isFromHub":true}' } const decryptToUnit8Array = base64ToUint8Array(res) @@ -54,7 +63,26 @@ Base64Message.decode = function (string, keys, ref) { } if (responseData.hasOwnProperty('message') && typeof responseData['message'] === 'string' && responseData['message'].length) { - const messageRep = responseData.message + if (responseData.message.includes('qortal://use-embed/')) { + const useEmbed1 = extensionToPointer(responseData.message) + const useEmbed2 = /(.*?)<\/newpointer>/g.exec(useEmbed1) + const useEmbed3 = encodedToChar(useEmbed2[1]) + + messageUseEmbed = parseQortalLink(useEmbed3) + addedFileStr = embedToString(messageUseEmbed) + + const useEmbed4 = responseData.message.split(useEmbed2[1]).join('') + + if (useEmbed4 === "

") { + messageRep = useEmbed4.split('

').join('

Qortal-Hub embed link

') + } else { + messageRep = useEmbed4 + } + } else { + messageRep = responseData.message + addedFileStr = ',"images":[""]' + } + const messageRep1 = messageRep.split('"').join('') const messageRep2 = messageRep1.split('

').join('"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"text","text":"') const messageRep3 = messageRep2.split('

').join('"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"text","text":"') @@ -77,11 +105,11 @@ Base64Message.decode = function (string, keys, ref) { } if (responseData.type === "edit") { - hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]},"images":[""],"repliedTo":"' + repliedToStr + '","version":3,"isEdited":true}' + hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]}' + addedFileStr + ',"repliedTo":"' + repliedToStr + '","version":3,"isEdited":true,"isFromHub":true}' } else if (responseData.type === "reaction") { - hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]},"images":[""],"repliedTo":"' + repliedToStr + '","version":3,"isReaction":true}' + hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]}' + addedFileStr + ',"repliedTo":"' + repliedToStr + '","version":3,"isReaction":true,"isFromHub":true}' } else { - hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]},"images":[""],"repliedTo":"' + repliedToStr + '","version":3}' + hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]}' + addedFileStr + ',"repliedTo":"' + repliedToStr + '","version":3,"isFromHub":true}' } const preparedString = hubString.split('').join('\\"') diff --git a/plugins/plugins/core/components/ChatScroller.js b/plugins/plugins/core/components/ChatScroller.js index c5ebbeb0..42b803e8 100644 --- a/plugins/plugins/core/components/ChatScroller.js +++ b/plugins/plugins/core/components/ChatScroller.js @@ -177,7 +177,7 @@ function processText(input) { }) ) } catch (error) { - console.log({ error }) + console.error({ error }) } }) @@ -1081,7 +1081,7 @@ class MessageTemplate extends LitElement { let version = 0 let isForwarded = false let isEdited = false - + let isFromHub = false try { const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage) @@ -1101,6 +1101,7 @@ class MessageTemplate extends LitElement { version = parsedMessageObj.version isForwarded = parsedMessageObj.type === 'forward' isEdited = parsedMessageObj.isEdited && true + isFromHub = parsedMessageObj.isFromHub && true if (parsedMessageObj.images && Array.isArray(parsedMessageObj.images) && parsedMessageObj.images.length > 0) { image = parsedMessageObj.images[0] @@ -1132,6 +1133,8 @@ class MessageTemplate extends LitElement { let hideit = hidemsg.includes(this.messageObj.sender) let forwarded = '' let edited = '' + let fromHubOk = '' + let fromHubNo = '' levelFounder = html`` @@ -1247,6 +1250,18 @@ class MessageTemplate extends LitElement { ` + fromHubOk = html` +

+ key   +
+ ` + + fromHubNo = html` +
+ key_off   +
+ ` + if (repliedToData) { try { repliedToData.decodedMessage = JSON.parse(repliedToData.decodedMessage) @@ -1536,9 +1551,10 @@ class MessageTemplate extends LitElement {

${attachment && attachment.attachmentName}

-

+ ${attachment.attachmentSize > 0 ? + `

${roundToNearestDecimal(attachment.attachmentSize)} mb -

+

` : ''} await this.downloadAttachment(attachment)} @@ -1662,18 +1678,21 @@ class MessageTemplate extends LitElement { ${this.isInProgress ? html`

${translate('chatpage.cchange91')}

` : this.isAgo ? html` + ${isFromHub ? html`${fromHubOk}` : html`${fromHubNo}`}
` : this.isIso ? html` + ${isFromHub ? html`${fromHubOk}` : html`${fromHubNo}`}
${new Date(this.messageObj.timestamp).toLocaleString()}
` : this.isBoth ? html` + ${isFromHub ? html`${fromHubOk}` : html`${fromHubNo}`}
${new Date(this.messageObj.timestamp).toLocaleString()} @@ -2176,7 +2195,7 @@ class MessageTemplate extends LitElement { await writeFile(fileHandle, blob).then(() => console.log('FILE SAVED')) } catch (error) { - console.log(error) + console.error(error) } } diff --git a/plugins/plugins/core/components/qdn-action-constants.js b/plugins/plugins/core/components/qdn-action-constants.js index 323f6f10..5f311f53 100644 --- a/plugins/plugins/core/components/qdn-action-constants.js +++ b/plugins/plugins/core/components/qdn-action-constants.js @@ -55,6 +55,125 @@ export const mimeToExtensionMap = { "application/x-bzip2": ".bz2", } +export const parseQortalLink = (link) => { + const prefix = "qortal://use-embed/" + + let params = {} + + if (!link.startsWith(prefix)) { + throw new Error("Invalid link format") + } + + const [typePart, queryPart] = link.slice(prefix.length).split("?") + const type = typePart.split("/")[0].toUpperCase() + + if (queryPart) { + const queryPairs = queryPart.split("&") + queryPairs.forEach((pair) => { + const [key, value] = pair.split("=") + if (key && value) { + const decodedKey = decodeURIComponent(key.trim()) + const decodedValue = value.trim().replace(/<\/?[^>]+(>|$)/g,"") + params[decodedKey] = decodedValue + } + }) + } + + return { type, ...params } +} + +export const extensionToPointer = (repString) => { + const replace00 = repString.split('qortal://use-embed/').join('qortal://use-embed/') + const replace01 = replace00.split('.pdf').join('.pdf') + const replace02 = replace01.split('.doc').join('.doc') + const replace03 = replace02.split('.xls').join('.xls') + const replace04 = replace03.split('.ppt').join('.ppt') + const replace05 = replace04.split('.odt').join('.odt') + const replace06 = replace05.split('.ods').join('.ods') + const replace07 = replace06.split('.odp').join('.odp') + const replace08 = replace07.split('.txt').join('.txt') + const replace09 = replace08.split('.csv').join('.csv') + const replace10 = replace09.split('.html').join('.html') + const replace11 = replace10.split('.xml').join('.xml') + const replace12 = replace11.split('.json').join('.json') + const replace13 = replace12.split('.jpg').join('.jpg') + const replace14 = replace13.split('.png').join('.png') + const replace15 = replace14.split('.gif').join('.gif') + const replace16 = replace15.split('.webp').join('.webp') + const replace17 = replace16.split('.svg').join('.svg') + const replace18 = replace17.split('.tif').join('.tif') + const replace19 = replace18.split('.bmp').join('.bmp') + const replace20 = replace19.split('.mp3').join('.mp3') + const replace21 = replace20.split('.ogg').join('.ogg') + const replace22 = replace21.split('.wav').join('.wav') + const replace23 = replace22.split('.webm').join('.webm') + const replace24 = replace23.split('.ogv').join('.ogv') + const replace25 = replace24.split('.avi').join('.avi') + const replace26 = replace25.split('.mov').join('.mov') + const replace27 = replace26.split('.wmv').join('.wmv') + const replace28 = replace27.split('.mpeg').join('.mpeg') + const replace29 = replace28.split('.3gp').join('.3gp') + const replace30 = replace29.split('.3g2').join('.3g2') + const replace31 = replace30.split('.mkv').join('.mkv') + const replace32 = replace31.split('.flv').join('.flv') + const replace33 = replace32.split('.zip').join('.zip') + const replace34 = replace33.split('.rar').join('.rar') + const replace35 = replace34.split('.tar').join('.tar') + const replace36 = replace35.split('.7z').join('.7z') + const replace37 = replace36.split('.gz').join('.gz') + const replace38 = replace37.split('.bz2').join('.bz2') + + return replace38 +} + +export const encodedToChar = (encodedString) => { + const encode01 = encodedString.split('&').join('&') + const encode02 = encode01.split(' ').join(' ') + const encode03 = encode02.split('<').join('<') + const encode04 = encode03.split('>').join('>') + const encode05 = encode04.split('"').join('"') + const encode06 = encode05.split('%20').join(' ') + const encode07 = encode06.split('%23').join('#') + const encode08 = encode07.split('%24').join('$') + const encode09 = encode08.split('%26').join('&') + const encode10 = encode09.split('%2B').join('+') + const encode11 = encode10.split('%2C').join(',') + const encode12 = encode11.split('%2F').join('/') + const encode13 = encode12.split('%3A').join(':') + const encode14 = encode13.split('%3B').join(';') + const encode15 = encode14.split('%3D').join('=') + const encode16 = encode15.split('%3F').join('?') + const encode17 = encode16.split('%40').join('@') + + return encode17 +} + +export const embedToString = (embed) => { + let embedString = '' + let embedService = '' + let embedName = '' + let embedIdentifier = '' + let embedAttachmentName = '' + + if (embed.type === "IMAGE") { + embedService = embed.service + embedName = embed.name + embedIdentifier = embed.identifier + embedString = ',"images":[{"service":"' + embedService + '","name":"' + embedName + '","identifier":"' + embedIdentifier + '"}],"isImageDeleted":false' + } else if (embed.type === "ATTACHMENT") { + embedService = embed.service + embedName = embed.name + embedIdentifier = embed.identifier + embedAttachmentName = embed.fileName + embedString = ',"attachments":[{"service":"' + embedService + '","name":"' + embedName + '","identifier":"' + embedIdentifier + '","attachmentName":"' + embedAttachmentName + '","attachmentSize":0}],"isAttachmentDeleted":false' + } else { + embedString = ',"images":[""]' + } + + return embedString +} + + export const listOfAllQortalRequests = [ 'IS_USING_GATEWAY', 'ADMIN_ACTION', @@ -69,6 +188,7 @@ export const listOfAllQortalRequests = [ 'DECRYPT_QORTAL_GROUP_DATA', 'ENCRYPT_DATA_WITH_SHARING_KEY', 'DECRYPT_DATA_WITH_SHARING_KEY', + 'DECRYPT_AESGCM', 'CREATE_TRADE_BUY_ORDER', 'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', diff --git a/plugins/plugins/core/components/qdn-action-types.js b/plugins/plugins/core/components/qdn-action-types.js index 25fc7f68..b0aaf8b5 100644 --- a/plugins/plugins/core/components/qdn-action-types.js +++ b/plugins/plugins/core/components/qdn-action-types.js @@ -33,6 +33,9 @@ export const ENCRYPT_DATA_WITH_SHARING_KEY = 'ENCRYPT_DATA_WITH_SHARING_KEY' // DECRYPT_DATA_WITH_SHARING_KEY export const DECRYPT_DATA_WITH_SHARING_KEY = 'DECRYPT_DATA_WITH_SHARING_KEY' +// DECRYPT_AESGCM +export const DECRYPT_AESGCM = 'DECRYPT_AESGCM' + // CREATE_TRADE_BUY_ORDER export const CREATE_TRADE_BUY_ORDER = 'CREATE_TRADE_BUY_ORDER' diff --git a/plugins/plugins/core/components/webworkerDecodeMessages.js b/plugins/plugins/core/components/webworkerDecodeMessages.js index e811cc52..7c37cad7 100644 --- a/plugins/plugins/core/components/webworkerDecodeMessages.js +++ b/plugins/plugins/core/components/webworkerDecodeMessages.js @@ -5,7 +5,12 @@ import { uint8ArrayToObject, decryptSingle } from './GroupEncryption.js' - +import { + extensionToPointer, + encodedToChar, + embedToString, + parseQortalLink +} from './qdn-action-constants.js' const nacl = {} @@ -2738,7 +2743,6 @@ class Curve25519 { } const base58Instant = new Base58() - const curve25519Instance = new Curve25519() self.addEventListener('message', async (e) => { @@ -2762,7 +2766,6 @@ self.addEventListener('message', async (e) => { } }) - const decode = (string, keys, ref) => { const binaryString = atob(string) const binaryLength = binaryString.length @@ -2785,13 +2788,16 @@ const decode = (string, keys, ref) => { } } else { let repliedToStr = '' + let addedFileStr = '' let messageStr = '' let hubString = '' + let messageRep = '' + let messageUseEmbed = {} 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}' + return '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"This message could not be decrypted"}]}]}' + addedFileStr + ',"repliedTo":"","version":3,"isFromHub":true}' } const decryptToUnit8Array = base64ToUint8Array(res) @@ -2810,7 +2816,26 @@ const decode = (string, keys, ref) => { } if (responseData.hasOwnProperty('message') && typeof responseData['message'] === 'string' && responseData['message'].length) { - const messageRep = responseData.message + if (responseData.message.includes('qortal://use-embed/')) { + const useEmbed1 = extensionToPointer(responseData.message) + const useEmbed2 = /(.*?)<\/newpointer>/g.exec(useEmbed1) + const useEmbed3 = encodedToChar(useEmbed2[1]) + + messageUseEmbed = parseQortalLink(useEmbed3) + addedFileStr = embedToString(messageUseEmbed) + + const useEmbed4 = responseData.message.split(useEmbed2[1]).join('') + + if (useEmbed4 === "

") { + messageRep = useEmbed4.split('

').join('

Qortal-Hub embed link

') + } else { + messageRep = useEmbed4 + } + } else { + messageRep = responseData.message + addedFileStr = ',"images":[""]' + } + const messageRep1 = messageRep.split('"').join('') const messageRep2 = messageRep1.split('

').join('"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"text","text":"') const messageRep3 = messageRep2.split('

').join('"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"hardBreak"},{"type":"text","text":"') @@ -2833,11 +2858,11 @@ const decode = (string, keys, ref) => { } if (responseData.type === "edit") { - hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]},"images":[""],"repliedTo":"' + repliedToStr + '","version":3,"isEdited":true}' + hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]}' + addedFileStr + ',"repliedTo":"' + repliedToStr + '","version":3,"isEdited":true,"isFromHub":true}' } else if (responseData.type === "reaction") { - hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]},"images":[""],"repliedTo":"' + repliedToStr + '","version":3,"isReaction":true}' + hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]}' + addedFileStr + ',"repliedTo":"' + repliedToStr + '","version":3,"isReaction":true,"isFromHub":true}' } else { - hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]},"images":[""],"repliedTo":"' + repliedToStr + '","version":3}' + hubString = '{"messageText":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"' + messageStr + '"}]}]}' + addedFileStr + ',"repliedTo":"' + repliedToStr + '","version":3,"isFromHub":true}' } const preparedString = hubString.split('').join('\\"') diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index d7c7f20f..c49dbbb5 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -1,29 +1,30 @@ -import { html, LitElement } from 'lit' -import { Epml } from '../../../../epml' +import {html, LitElement} from 'lit' +import {Epml} from '../../../../epml' +import {Sha256} from 'asmcrypto.js' import { - Loader, - publishData, - getPublishesFromAdmins, - getGroupAdmins, - getPublishesFromAdminsAdminSpace, - isUsingPublicNode, - createBuyOrderTx, - requestQueueGetAtAddresses, - getUserWalletFunc, - tradeBotCreateRequest, cancelTradeOfferTradeBot, - processTransactionV2 + createBuyOrderTx, + getGroupAdmins, + getPublishesFromAdmins, + getPublishesFromAdminsAdminSpace, + getUserWalletFunc, + isUsingPublicNode, + Loader, + processTransactionV2, + publishData, + requestQueueGetAtAddresses, + tradeBotCreateRequest } from '../../../utils/classes' -import { appendBuffer } from '../../../utils/utilities' -import { QORT_DECIMALS } from '../../../../../crypto/api/constants' -import { mimeToExtensionMap, listOfAllQortalRequests } from '../../components/qdn-action-constants' +import {appendBuffer} from '../../../utils/utilities' +import {QORT_DECIMALS} from '../../../../../crypto/api/constants' +import {listOfAllQortalRequests} from '../../components/qdn-action-constants' import { - uint8ArrayToObject, - validateSecretKey, - encryptSingle, - decryptSingle, createSymmetricKeyAndNonce, - decryptGroupEncryptionWithSharingKey + decryptGroupEncryptionWithSharingKey, + decryptSingle, + encryptSingle, + uint8ArrayToObject, + validateSecretKey } from '../../components/GroupEncryption' import { base64ToUint8Array, @@ -33,28 +34,28 @@ import { encryptDataGroup, encryptDataGroupNew, fileToBase64, - uint8ArrayStartsWith, - uint8ArrayToBase64, - base64ToBlobUrl, groupSecretkeys, objectToBase64, - roundUpToDecimals + roundUpToDecimals, + uint8ArrayStartsWith, + uint8ArrayToBase64 } from '../../components/qdn-action-encryption' -import { webBrowserStyles, webBrowserModalStyles } from '../../components/plugins-css' +import {webBrowserModalStyles, webBrowserStyles} from '../../components/plugins-css' import * as actions from '../../components/qdn-action-types' import isElectron from 'is-electron' import ShortUniqueId from 'short-unique-id' -import FileSaver from 'file-saver' import WebWorker from 'web-worker:./computePowWorkerFile.js' import WebWorkerChat from 'web-worker:./computePowWorker.js' import Base58 from '../../../../../crypto/api/deps/Base58' +import ed2curve from '../../../../../crypto/api/deps/ed2curve' import nacl from '../../../../../crypto/api/deps/nacl-fast' import '@material/mwc-button' import '@material/mwc-icon' import '@material/mwc-checkbox' // Multi language support -import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' +import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' + registerTranslateConfig({ loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) @@ -148,11 +149,11 @@ class WebBrowser extends LitElement { } else { displayUrl = 'qortal://' + this.service + '/' + this.name - if (this.identifier && this.identifier != 'null' && this.identifier != 'default') { + if (this.identifier && this.identifier !== 'null' && this.identifier !== 'default') { displayUrl = displayUrl.concat('/' + this.identifier) } - if (this.path != null && this.path != '/') { + if (this.path != null && this.path !== '/') { displayUrl = displayUrl.concat(this.path) } } @@ -192,7 +193,7 @@ class WebBrowser extends LitElement { this.url = `${this.link}` } else { // Normal mode - this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''}?theme=${this.theme}&identifier=${(this.identifier != null && this.identifier != 'null') ? this.identifier : ''}` + this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''}?theme=${this.theme}&identifier=${(this.identifier != null && this.identifier !== 'null') ? this.identifier : ''}` } } @@ -252,7 +253,7 @@ class WebBrowser extends LitElement { this.goBackToList()} title="${translate('browserpage.bchange3')}" class="address-bar-button"> home - + ${this.renderFullScreen()} this.delete()} title="${translate('browserpage.bchange4')} ${this.service} ${this.name} ${translate('browserpage.bchange5')}" class="address-bar-button float-right"> delete @@ -305,7 +306,7 @@ class WebBrowser extends LitElement { } window.addEventListener('message', async (event) => { - if (event == null || event.data == null || event.data.length == 0 || event.data.action == null) { + if (event == null || event.data == null || event.data.length === 0 || event.data.action == null) { return } @@ -314,10 +315,9 @@ class WebBrowser extends LitElement { switch (data.action) { case actions.IS_USING_PUBLIC_NODE: { - const res = await isUsingPublicNode() - response = res - break + response = await isUsingPublicNode() } + break case actions.ADMIN_ACTION: { let type = data.type @@ -375,7 +375,8 @@ class WebBrowser extends LitElement { includeValueInBody = true break default: - throw new Error(`Unknown admin action type: ${type}`) + console.error(`Unknown admin action type: ${type}`) + break } // Set up options for the API call let options = { @@ -402,13 +403,13 @@ class WebBrowser extends LitElement { data['error'] = `User declined admin action: ${type}` response = JSON.stringify(data) } - break } + break case actions.SHOW_ACTIONS: { response = listOfAllQortalRequests - break } + break case actions.GET_USER_ACCOUNT: { let skip = false @@ -436,9 +437,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = "User declined to share account details" response = JSON.stringify(data) - break } } + break case actions.ENCRYPT_DATA: { try { @@ -469,9 +470,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message || "Error in encrypting data" response = JSON.stringify(data) - break } } + break case actions.DECRYPT_DATA: { const { encryptedData, publicKey } = data @@ -510,12 +511,12 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message || "Error in decrypting data" response = JSON.stringify(data) - break } } + break case actions.ENCRYPT_QORTAL_GROUP_DATA: { - let data64 = data.data64 || data.base64 + let data64 = data.data64 ? data.data64 : data.base64 let groupId = data.groupId let isAdmins = data.isAdmins let dataSentBack = {} @@ -542,7 +543,6 @@ class WebBrowser extends LitElement { ) { secretKeyObject = groupSecretkeys[groupId].secretKeyObject } - if(!secretKeyObject) { const { names } = await getGroupAdmins(groupId) const publish = await getPublishesFromAdmins(names, groupId) @@ -551,10 +551,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(dataSentBack) break } - const res = await parentEpml.request('apiCall', { + const resData = await parentEpml.request('apiCall', { + type: 'api', url: `/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${publish.identifier}?encoding=base64` }) - const resData = await res.text() const decryptedKey = await this.decryptResourceQDN(resData) const dataint8Array = base64ToUint8Array(decryptedKey.data) const decryptedKeyToObject = uint8ArrayToObject(dataint8Array) @@ -564,7 +564,8 @@ class WebBrowser extends LitElement { break } secretKeyObject = decryptedKeyToObject - groupSecretkeys[groupId] = { + let groupSecretkeys = {} + groupSecretkeys[`${groupId}`] = { secretKeyObject, timestamp: Date.now() } @@ -586,10 +587,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(dataSentBack) break } - const res = await parentEpml.request('apiCall', { + const resData = await parentEpml.request('apiCall', { + type: 'api', url: `/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${publish.identifier}?encoding=base64` }) - const resData = await res.text() const decryptedKey = await this.decryptResourceQDN(resData) const dataint8Array = base64ToUint8Array(decryptedKey.data) const decryptedKeyToObject = uint8ArrayToObject(dataint8Array) @@ -599,26 +600,25 @@ class WebBrowser extends LitElement { break } secretKeyObject = decryptedKeyToObject + let groupSecretkeys = {} groupSecretkeys[`admins-${groupId}`] = { secretKeyObject, timestamp: Date.now() } } } - const resGroupEncryptedResource = encryptSingle({ - data64, secretKeyObject: secretKeyObject - }) + const resGroupEncryptedResource = encryptSingle(data64, secretKeyObjec) if (resGroupEncryptedResource) { - return resGroupEncryptedResource + response = resGroupEncryptedResource } else { dataSentBack['error'] = "Unable to encrypt" response = JSON.stringify(dataSentBack) - break } } + break case actions.DECRYPT_QORTAL_GROUP_DATA: { - let data64 = data.data64 || data.base64 + let data64 = data.daat64 ? data.daat64 : data.base64 let groupId = data.groupId let isAdmins = data.isAdmins let dataSentBack = {} @@ -642,7 +642,6 @@ class WebBrowser extends LitElement { ) { secretKeyObject = groupSecretkeys[groupId].secretKeyObject } - if (!secretKeyObject) { const { names } = await getGroupAdmins(groupId) const publish = await getPublishesFromAdmins(names, groupId) @@ -651,10 +650,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(dataSentBack) break } - const res = await parentEpml.request('apiCall', { + const resData = await parentEpml.request('apiCall', { + type: 'api', url: `/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${publish.identifier}?encoding=base64` }) - const resData = await res.text() const decryptedKey = await this.decryptResourceQDN(resData) const dataint8Array = base64ToUint8Array(decryptedKey.data) const decryptedKeyToObject = uint8ArrayToObject(dataint8Array) @@ -664,7 +663,8 @@ class WebBrowser extends LitElement { break } secretKeyObject = decryptedKeyToObject - groupSecretkeys[groupId] = { + let groupSecretkeys ={} + groupSecretkeys[`${groupId}`] = { secretKeyObject, timestamp: Date.now() } @@ -686,10 +686,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(dataSentBack) break } - const res = await parentEpml.request('apiCall', { + const resData = await parentEpml.request('apiCall', { + type: 'api', url: `/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${publish.identifier}?encoding=base64` }) - const resData = await res.text() const decryptedKey = await this.decryptResourceQDN(resData) const dataint8Array = base64ToUint8Array(decryptedKey.data) const decryptedKeyToObject = uint8ArrayToObject(dataint8Array) @@ -699,23 +699,22 @@ class WebBrowser extends LitElement { break } secretKeyObject = decryptedKeyToObject + let groupSecretkeys ={} groupSecretkeys[`admins-${groupId}`] = { secretKeyObject, timestamp: Date.now() } } } - const resGroupDecryptResource = decryptSingle({ - data64, secretKeyObject: secretKeyObject, skipDecodeBase64: true - }) + const resGroupDecryptResource = decryptSingle(data64, secretKeyObject, false) if (resGroupDecryptResource) { - return resGroupDecryptResource + response = resGroupDecryptResource } else { dataSentBack['error'] = "Unable to decrypt" response = JSON.stringify(dataSentBack) - break } } + break case actions.ENCRYPT_DATA_WITH_SHARING_KEY: { let data64 = data.data64 || data.base64 @@ -749,9 +748,9 @@ class WebBrowser extends LitElement { } else { dataSentBack['error'] = "Unable to encrypt" response = JSON.stringify(dataSentBack) - break } } + break case actions.DECRYPT_DATA_WITH_SHARING_KEY: { let dataSentBack = {} @@ -771,9 +770,82 @@ class WebBrowser extends LitElement { } else { dataSentBack['error'] = "No data in the decrypted resource" response = JSON.stringify(dataSentBack) - break } } + break + + case actions.DECRYPT_AESGCM: { + const requiredFields = ["encryptedData", "iv", "senderPublicKey"] + const missingFields = [] + let dataSentBack = {} + requiredFields.forEach((field) => { + if (!data[field]) { + missingFields.push(field) + } + }) + if (missingFields.length > 0) { + const missingFieldsString = missingFields.join(', ') + const tryAgain = get("walletpage.wchange44") + await showErrorAndWait( + "MISSING_FIELDS", + { + id1: missingFieldsString, + id2: tryAgain + } + ) + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` + response = JSON.stringify(dataSentBack) + break + } + const encryptedData = data.encryptedData + const iv = data.iv + const senderPublicKeyBase58 = data.senderPublicKey + // Decode keys and IV + const senderPublicKey = Base58.decode(senderPublicKeyBase58) + const uint8PrivateKey = window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey + // Convert ed25519 keys to Curve25519 + const convertedPrivateKey = ed2curve.convertSecretKey(uint8PrivateKey) + const convertedPublicKey = ed2curve.convertPublicKey(senderPublicKey) + // Generate shared secret + const sharedSecret = new Uint8Array(32) + nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) + // Derive encryption key + let encryptionKey = new Uint8Array(32) + encryptionKey = new Sha256().process(sharedSecret).finish().result + // Convert IV and ciphertext from Base64 + const base64ToUint8Array = (base64) => Uint8Array.from(atob(base64), c => c.charCodeAt(0)) + const ivUint8Array = base64ToUint8Array(iv) + const ciphertext = base64ToUint8Array(encryptedData) + // Validate IV and key lengths + if (ivUint8Array.length !== 12) { + let myMsg1 = get("managegroup.mg58") + let myMsg2 = get("walletpage.wchange44") + await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) + response = '{"error": "Invalid IV: AES-GCM requires a 12-byte IV."}' + break + } + if (encryptionKey.length !== 32) { + let myMsg1 = get("managegroup.mg58") + let myMsg2 = get("walletpage.wchange44") + await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) + response = '{"error": "Invalid key: AES-GCM requires a 256-bit key."}' + break + } + try { + // Decrypt data + const algorithm = { name: "AES-GCM", iv: ivUint8Array } + const cryptoKey = await crypto.subtle.importKey("raw", encryptionKey, algorithm, false, ["decrypt"]) + const decryptedArrayBuffer = await crypto.subtle.decrypt(algorithm, cryptoKey, ciphertext) + // Return decrypted data as Base64 + return uint8ArrayToBase64(new Uint8Array(decryptedArrayBuffer)) + } catch (error) { + let myMsg1 = get("managegroup.mg58") + let myMsg2 = get("walletpage.wchange44") + await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) + response = '{"error": "Failed to decrypt the message. Ensure the data and keys are correct."}' + } + } + break case actions.CREATE_TRADE_BUY_ORDER: { const node = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] @@ -796,8 +868,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -809,7 +880,6 @@ class WebBrowser extends LitElement { const url = `${nodeUrl}/crosschain/trade/${atAddress}` const resAddress = await fetch(url) const resData = await resAddress.json() - if (foreignBlockchain !== resData.foreignBlockchain) { let myMsg1 = get("modals.mpchange1") let myMsg2 = get("walletpage.wchange44") @@ -817,7 +887,6 @@ class WebBrowser extends LitElement { response = '{"error": "All requested ATs need to be of the same foreign Blockchain."}' throw new Error("All requested ATs need to be of the same foreign Blockchain.") } - return resData }) ) @@ -873,6 +942,7 @@ class WebBrowser extends LitElement { break } } + break case actions.CREATE_TRADE_SELL_ORDER: { const requiredFields = ["qortAmount", "foreignBlockchain", "foreignAmount"] @@ -893,8 +963,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -952,6 +1021,7 @@ class WebBrowser extends LitElement { break } } + break case actions.CANCEL_TRADE_SELL_ORDER: { const requiredFields = ["atAddress"] @@ -972,8 +1042,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1038,6 +1107,7 @@ class WebBrowser extends LitElement { break } } + break case actions.GET_LIST_ITEMS: { const requiredFields = ['list_name'] @@ -1058,8 +1128,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1083,6 +1152,7 @@ class WebBrowser extends LitElement { url: `/lists/${data.list_name}?apiKey=${this.getApiKey()}` }) response = JSON.stringify(list) + break } catch (error) { let myMsg1 = get("modals.mpchange16") let myMsg2 = get("walletpage.wchange44") @@ -1090,7 +1160,6 @@ class WebBrowser extends LitElement { const data = {} data['error'] = "Error in retrieving list." response = JSON.stringify(data) - } finally { break } } else { @@ -1098,9 +1167,9 @@ class WebBrowser extends LitElement { let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) response = '{"error": "User declined request"}' - break } } + break case actions.ADD_LIST_ITEMS: { const requiredFields = ['list_name', 'items'] @@ -1121,8 +1190,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1150,6 +1218,7 @@ class WebBrowser extends LitElement { 'Content-Type': 'application/json' } }) + break } catch (error) { let myMsg1 = get("modals.mpchange17") let myMsg2 = get("walletpage.wchange44") @@ -1157,7 +1226,6 @@ class WebBrowser extends LitElement { const data = {} data['error'] = "Error in adding to list." response = JSON.stringify(data) - } finally { break } } else { @@ -1165,9 +1233,9 @@ class WebBrowser extends LitElement { let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) response = '{"error": "User declined request"}' - break } } + break case actions.DELETE_LIST_ITEM: { const requiredFields = ['list_name', 'item'] @@ -1188,8 +1256,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1217,6 +1284,7 @@ class WebBrowser extends LitElement { 'Content-Type': 'application/json' } }) + break } catch (error) { let myMsg1 = get("modals.mpchange18") let myMsg2 = get("walletpage.wchange44") @@ -1224,7 +1292,6 @@ class WebBrowser extends LitElement { const data = {} data['error'] = "Error in delete list." response = JSON.stringify(data) - } finally { break } } else { @@ -1232,9 +1299,9 @@ class WebBrowser extends LitElement { let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) response = '{"error": "User declined request"}' - break } } + break case actions.GET_FRIENDS_LIST: { let skip = false @@ -1252,6 +1319,7 @@ class WebBrowser extends LitElement { let list = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") list = list.map((friend) => friend.name || "") response = JSON.stringify(list) + break } catch (error) { let myMsg1 = get("modals.mpchange19") let myMsg2 = get("walletpage.wchange44") @@ -1259,7 +1327,6 @@ class WebBrowser extends LitElement { const data = {} data['error'] = "Error in retrieving friends list." response = JSON.stringify(data) - } finally { break } } else { @@ -1267,9 +1334,9 @@ class WebBrowser extends LitElement { let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) response = '{"error": "User declined request"}' - break } } + break case actions.LINK_TO_QDN_RESOURCE: case actions.QDN_RESOURCE_DISPLAYED: @@ -1277,14 +1344,14 @@ class WebBrowser extends LitElement { // Note: don't update this.url here, as we don't want to force reload the iframe each time. if (this.preview != null && this.preview.length > 0) { this.displayUrl = translate("appspage.schange40") - return + break } let url = 'qortal://' + data.service + '/' + data.name this.path = data.path != null ? (data.path.startsWith('/') ? '' : '/') + data.path : null - if (data.identifier != null && data.identifier != '' && data.identifier != 'default') { + if (data.identifier != null && data.identifier !== '' && data.identifier !== 'default') { url = url.concat('/' + data.identifier) } - if (this.path != null && this.path != '/') { + if (this.path != null && this.path !== '/') { url = url.concat(this.path) } this.name = data.name @@ -1304,7 +1371,7 @@ class WebBrowser extends LitElement { service: data.service, id: tabId ? tabId : '' })) - return + break case actions.SET_TAB_NOTIFICATIONS: { const { count } = data @@ -1327,8 +1394,8 @@ class WebBrowser extends LitElement { count: count })) response = true - break } + break case actions.PUBLISH_QDN_RESOURCE: { // optional fields: encrypt:boolean recipientPublicKey:string @@ -1350,8 +1417,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1422,7 +1488,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - } const res2 = await showModalAndWait( actions.PUBLISH_QDN_RESOURCE, @@ -1489,8 +1554,8 @@ class WebBrowser extends LitElement { // TODO: prompt user for publish. If they confirm, call `POST /arbitrary/{service}/{name}/{identifier}/base64` and sign+process transaction // then set the response string from the core to the `response` variable (defined above) // If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}` - break } + break case actions.PUBLISH_MULTIPLE_QDN_RESOURCES: { const requiredFields = ['resources'] @@ -1512,8 +1577,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1591,7 +1655,6 @@ class WebBrowser extends LitElement { }) continue } - const service = resource.service const name = resource.name let identifier = resource.identifier @@ -1699,8 +1762,8 @@ class WebBrowser extends LitElement { break } response = true - break } + break case actions.VOTE_ON_POLL: { const requiredFields = ['pollName', 'optionIndex'] @@ -1721,8 +1784,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1768,8 +1830,8 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - break } + break case actions.CREATE_POLL: { const requiredFields = ['pollName', 'pollDescription', 'pollOptions', 'pollOwnerAddress'] @@ -1790,8 +1852,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -1813,8 +1874,8 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - break } + break case actions.OPEN_NEW_TAB: { if (!data.qortalLink) { @@ -1837,9 +1898,9 @@ class WebBrowser extends LitElement { const obj = {} obj['error'] = "Invalid qortal link." response = JSON.stringify(obj) - break } } + break case actions.NOTIFICATIONS_PERMISSION: { try { @@ -1858,16 +1919,25 @@ class WebBrowser extends LitElement { break } } catch (error) { - break + console.error(error) } } + break case actions.SEND_LOCAL_NOTIFICATION: { const { title, url, icon, message } = data try { const id = `appNotificationList-${this.selectedAddress.address}` const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null - if (!checkData || !checkData[this.name]) throw new Error('App not on permission list') + if (!checkData || !checkData[this.name]) { + let myMsg1 = get("modals.mpchange34") + let myMsg2 = get("walletpage.wchange44") + await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) + const obj = {} + obj['error'] = "App not on permission list" + response = JSON.stringify(obj) + break + } const appInfo = checkData[this.name] const lastNotification = appInfo.lastNotification const interval = appInfo.interval @@ -1881,7 +1951,13 @@ class WebBrowser extends LitElement { this.updateLastNotification(id, this.name) break } else { - throw new Error(`invalid data`) + let myMsg1 = get("modals.mpchange34") + let myMsg2 = get("walletpage.wchange44") + await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) + const obj = {} + obj['error'] = "Invalid data" + response = JSON.stringify(obj) + break } } else if (!lastNotification) { parentEpml.request('showNotification', { @@ -1891,11 +1967,13 @@ class WebBrowser extends LitElement { this.updateLastNotification(id) break } else { - let myMsg1 = get("modals.mpchange27") + let myMsg1 = get("modals.mpchange34") let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) - throw new Error(`invalid data.`) - } + const obj = {} + obj['error'] = "Invalid data" + response = JSON.stringify(obj) + break } } catch (error) { let myMsg1 = get("modals.mpchange35") let myMsg2 = get("walletpage.wchange44") @@ -1903,9 +1981,9 @@ class WebBrowser extends LitElement { const obj = {} obj['error'] = error.message ? error.message : get("modals.mpchange35") response = JSON.stringify(obj) - break } } + break case actions.SEND_CHAT_MESSAGE: { const message = data.message @@ -2073,8 +2151,8 @@ class WebBrowser extends LitElement { // TODO: prompt user to send chat message. If they confirm, sign+process a CHAT transaction // then set the response string from the core to the `response` variable (defined above) // If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}` - break } + break case actions.JOIN_GROUP: { const requiredFields = ['groupId'] @@ -2095,8 +2173,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2173,118 +2250,7 @@ class WebBrowser extends LitElement { break } } - - case actions.SAVE_FILE: { - try { - const requiredFields = ['filename', 'blob'] - const missingFields = [] - let dataSentBack = {} - requiredFields.forEach((field) => { - if (!data[field]) { - missingFields.push(field) - } - }) - if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', ') - const tryAgain = get("walletpage.wchange44") - await showErrorAndWait( - "MISSING_FIELDS", - { - id1: missingFieldsString, - id2: tryAgain - } - ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg - response = JSON.stringify(dataSentBack) - break - } - const filename = data.filename - const blob = data.blob - const res = await showModalAndWait( - actions.SAVE_FILE, - { - filename - } - ) - if (res.action === 'reject') { - let myMsg1 = get("transactions.declined") - let myMsg2 = get("walletpage.wchange44") - await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) - response = '{"error": "User declined request"}' - break - } - const mimeType = blob.type || data.mimeType - let backupExention = filename.split('.').pop() - if (backupExention) { - backupExention = '.' + backupExention - } - const fileExtension = mimeToExtensionMap[mimeType] || backupExention - let fileHandleOptions = {} - if (!mimeType) { - let myMsg1 = get("modals.mpchange45") - let myMsg2 = get("walletpage.wchange44") - await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) - const obj = {} - obj['error'] = 'A mime type could not be derived.' - response = JSON.stringify(obj) - break - } - if (!fileExtension) { - let myMsg1 = get("modals.mpchange46") - let myMsg2 = get("walletpage.wchange44") - await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) - const obj = {} - obj['error'] = 'A file extension could not be derived.' - response = JSON.stringify(obj) - break - } - if (fileExtension && mimeType) { - fileHandleOptions = { - accept: { - [mimeType]: [fileExtension] - } - } - } - try { - const fileHandle = await self.showSaveFilePicker({ - suggestedName: filename, - types: [ - { - description: mimeType, - ...fileHandleOptions - } - ] - }) - const writeFile = async (fileHandle, contents) => { - const writable = await fileHandle.createWritable() - await writable.write(contents) - await writable.close() - } - writeFile(fileHandle, blob).then(() => console.log("FILE SAVED")) - } catch (error) { - if (error.name === 'AbortError') { - let myMsg1 = get("modals.mpchange47") - let myMsg2 = get("walletpage.wchange44") - await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) - const obj = {} - obj['error'] = 'User declined the download.' - response = JSON.stringify(obj) - break - } - FileSaver.saveAs(blob, filename) - } - response = JSON.stringify(true) - } catch (error) { - let myMsg1 = get("modals.mpchange48") - let myMsg2 = get("walletpage.wchange44") - await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) - const obj = {} - obj['error'] = error.message ? error.message : get("modals.mpchange48") - response = JSON.stringify(obj) - } break - } case actions.DEPLOY_AT: { const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'] @@ -2305,8 +2271,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2314,18 +2279,19 @@ class WebBrowser extends LitElement { this.loader.show() const resDeployAt = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, data.type) response = JSON.stringify(resDeployAt) + this.loader.hide() + break } catch (error) { + this.loader.hide() let myMsg1 = get("modals.mpchange49") let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) const obj = {} obj['error'] = error.message ? error.message : get("modals.mpchange49") response = JSON.stringify(obj) - } finally { - this.loader.hide() } - break } + break case actions.GET_PROFILE_DATA: { const defaultProperties = ['tagline', 'bio', 'wallets'] @@ -2347,8 +2313,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2421,9 +2386,9 @@ class WebBrowser extends LitElement { const obj = {} obj['error'] = error.message ? error.message : get("modals.mpchange52") response = JSON.stringify(obj) - break } } + break case actions.SET_PROFILE_DATA: { const requiredFields = ['property', 'data'] @@ -2444,8 +2409,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2511,8 +2475,8 @@ class WebBrowser extends LitElement { obj['error'] = error.message ? error.message : get("modals.mpchange53") response = JSON.stringify(obj) } - break } + break case actions.OPEN_PROFILE: { const requiredFields = ['name'] @@ -2533,8 +2497,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2552,9 +2515,9 @@ class WebBrowser extends LitElement { const obj = {} obj['error'] = error.message ? error.message : get("modals.mpchange54") response = JSON.stringify(obj) - break } } + break case actions.GET_USER_WALLET: { const requiredFields = ['coin'] @@ -2575,8 +2538,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2635,6 +2597,7 @@ class WebBrowser extends LitElement { break } } + break case actions.GET_WALLET_BALANCE: { const requiredFields = ['coin'] @@ -2657,8 +2620,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2683,16 +2645,16 @@ class WebBrowser extends LitElement { response = await parentEpml.request('apiCall', { url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}` }) + this.loader.hide() + break } catch (error) { this.loader.hide() let myMsg1 = get("browserpage.bchange21") let myMsg2 = get("walletpage.wchange44") - await showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) + await showErrorAndWait("ACTION_FAILED", {id1: myMsg1, id2: myMsg2}) const data = {} data['error'] = error.message ? error.message : get("browserpage.bchange21") response = JSON.stringify(data) - } finally { - this.loader.hide() } } else { let _url = `` @@ -2740,9 +2702,11 @@ class WebBrowser extends LitElement { const data = {} data['error'] = get("browserpage.bchange21") response = JSON.stringify(data) - return + break } else { + this.loader.hide() response = (Number(res) / 1e8).toFixed(8) + break } } catch (error) { this.loader.hide() @@ -2752,9 +2716,7 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("browserpage.bchange21") response = JSON.stringify(data) - return - } finally { - this.loader.hide() + break } } } else if (res3.action === 'reject') { @@ -2762,9 +2724,10 @@ class WebBrowser extends LitElement { let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) response = '{"error": "User declined request"}' + break } - break } + break case actions.GET_USER_WALLET_INFO: { const requiredFields = ['coin'] @@ -2785,8 +2748,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2829,8 +2791,8 @@ class WebBrowser extends LitElement { await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) response = '{"error": "User declined request"}' } - break } + break case actions.GET_CROSSCHAIN_SERVER_INFO: { const requiredFields = ['coin'] @@ -2851,8 +2813,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2879,8 +2840,8 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - break } + break case actions.GET_TX_ACTIVITY_SUMMARY: { const requiredFields = ['coin'] @@ -2901,8 +2862,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -2917,6 +2877,7 @@ class WebBrowser extends LitElement { 'Content-Type': 'application/json' } }) + break } catch (error) { let myMsg1 = get("modals.mpchange56") let myMsg2 = get("walletpage.wchange44") @@ -2924,10 +2885,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange56") response = JSON.stringify(data) - } finally { - break } } + break case actions.GET_FOREIGN_FEE: { const requiredFields = ['coin','type'] @@ -2948,13 +2908,12 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } try { - let coin = data.coin + let coin = data.coin.toLowerCase() let type = data.type response = await parentEpml.request('apiCall', { type: 'api', @@ -2965,6 +2924,7 @@ class WebBrowser extends LitElement { 'Content-Type': 'application/json' }, }) + break } catch (error) { let myMsg1 = get("modals.mpchange57") let myMsg2 = get("walletpage.wchange44") @@ -2972,10 +2932,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange57") response = JSON.stringify(data) - } finally { - break } } + break case actions.UPDATE_FOREIGN_FEE: { const requiredFields = ['coin','type'] @@ -2996,13 +2955,12 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } try { - let coin = data.coin + let coin = data.coin.toLowerCase() let type = data.type let value = data.value response = await parentEpml.request('apiCall', { @@ -3015,6 +2973,7 @@ class WebBrowser extends LitElement { }, body: `${value}` }) + break } catch (error) { let myMsg1 = get("modals.mpchange58") let myMsg2 = get("walletpage.wchange44") @@ -3022,10 +2981,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange58") response = JSON.stringify(data) - } finally { - break } } + break case actions.GET_SERVER_CONNECTION_HISTORY: { const requiredFields = ['coin'] @@ -3046,8 +3004,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -3062,6 +3019,7 @@ class WebBrowser extends LitElement { 'Content-Type': 'application/json' }, }) + break } catch (error) { let myMsg1 = get("modals.mpchange59") let myMsg2 = get("walletpage.wchange44") @@ -3069,10 +3027,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange59") response = JSON.stringify(data) - } finally { - break } } + break case actions.SET_CURRENT_FOREIGN_SERVER: { const requiredFields = ['coin'] @@ -3093,13 +3050,12 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } try { - let coin = data.coin + let coin = data.coin.toLowerCase() let host = data.host let port = data.port let type = data.type @@ -3119,6 +3075,7 @@ class WebBrowser extends LitElement { }, body: `${bodyToString}` }) + break } catch (error) { let myMsg1 = get("modals.mpchange60") let myMsg2 = get("walletpage.wchange44") @@ -3126,10 +3083,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange60") response = JSON.stringify(data) - } finally { - break } } + break case actions.ADD_FOREIGN_SERVER: { const requiredFields = ['coin'] @@ -3150,13 +3106,12 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } try { - let coin = data.coin + let coin = data.coin.toLowerCase() let host = data.host let port = data.port let type = data.type @@ -3176,6 +3131,7 @@ class WebBrowser extends LitElement { }, body: `${bodyToString}` }) + break } catch (error) { let myMsg1 = get("modals.mpchange61") let myMsg2 = get("walletpage.wchange44") @@ -3183,10 +3139,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange61") response = JSON.stringify(data) - } finally { - break } } + break case actions.REMOVE_FOREIGN_SERVER: { const requiredFields = ['coin'] @@ -3207,13 +3162,12 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } try { - let coin = data.coin + let coin = data.coin.toLowerCase() let host = data.host let port = data.port let type = data.type @@ -3233,6 +3187,7 @@ class WebBrowser extends LitElement { }, body: `${bodyToString}` }) + break } catch (error) { let myMsg1 = get("modals.mpchange62") let myMsg2 = get("walletpage.wchange44") @@ -3240,10 +3195,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange62") response = JSON.stringify(data) - } finally { - break } } + break case actions.GET_DAY_SUMMARY: { try { @@ -3251,6 +3205,7 @@ class WebBrowser extends LitElement { type: 'api', url: `/admin/summary?apiKey=${this.getApiKey()}` }) + break } catch (error) { let myMsg1 = get("modals.mpchange63") let myMsg2 = get("walletpage.wchange44") @@ -3258,10 +3213,9 @@ class WebBrowser extends LitElement { const data = {} data['error'] = error.message ? error.message : get("modals.mpchange63") response = JSON.stringify(data) - } finally { - break } } + break case actions.SIGN_TRANSACTION: { const signNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] @@ -3284,8 +3238,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -3380,9 +3333,9 @@ class WebBrowser extends LitElement { let myMsg2 = get("walletpage.wchange44") await showErrorAndWait("DECLINED_REQUEST", { id1: myMsg1, id2: myMsg2 }) response = '{"error": "User declined request"}' - break } } + break case actions.SEND_COIN: { const requiredFields = ['coin', 'amount'] @@ -3403,8 +3356,7 @@ class WebBrowser extends LitElement { id2: tryAgain } ) - const errorMsg = `Missing fields: ${missingFieldsString}` - dataSentBack['error'] = errorMsg + dataSentBack['error'] = `Missing fields: ${missingFieldsString}` response = JSON.stringify(dataSentBack) break } @@ -3577,7 +3529,7 @@ class WebBrowser extends LitElement { this.loader.hide() let myMsg1 = txnResponse.message let myMsg2 = get("walletpage.wchange44") - showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) + showErrorAndWait("ACTION_FAILED", { id1: myMsg1, id2: myMsg2 }) throw new Error(txnResponse.message) } else if (txnResponse.success === true && !txnResponse.data.error) { this.loader.hide() @@ -4201,10 +4153,11 @@ class WebBrowser extends LitElement { break } } - break + break + default: console.log('Unhandled message: ' + JSON.stringify(data)) - return + break } // Parse response let responseObj @@ -4234,7 +4187,7 @@ class WebBrowser extends LitElement { } renderFullScreen() { - if (window.innerHeight == screen.height) { + if (window.innerHeight === screen.height) { return html` this.exitFullScreen()} @@ -4862,7 +4815,7 @@ class WebBrowser extends LitElement { } goBackToList() { - if (this.service == "APP") { + if (this.service === "APP") { this.exitFullScreen() window.location = '../../q-app/index.html' } @@ -4908,7 +4861,7 @@ class WebBrowser extends LitElement { // Remove it first by filtering the list - doing it this way ensures the UI updates // immediately, as apposed to only adding if it doesn't already exist this.followedNames = this.followedNames.filter( - (item) => item != name + (item) => item !== name ) this.followedNames.push(name) } else { @@ -4932,7 +4885,7 @@ class WebBrowser extends LitElement { if (ret === true) { // Successfully unfollowed - remove from local list this.followedNames = this.followedNames.filter( - (item) => item != name + (item) => item !== name ) } else { let err2string = get('browserpage.bchange12') @@ -4957,7 +4910,7 @@ class WebBrowser extends LitElement { // Remove it first by filtering the list - doing it this way ensures the UI updates // immediately, as apposed to only adding if it doesn't already exist this.blockedNames = this.blockedNames.filter( - (item) => item != name + (item) => item !== name ) this.blockedNames.push(name) } else { @@ -4980,7 +4933,7 @@ class WebBrowser extends LitElement { }) if (ret === true) { // Successfully unblocked - remove from local list - this.blockedNames = this.blockedNames.filter((item) => item != name) + this.blockedNames = this.blockedNames.filter((item) => item !== name) } else { let err4string = get('browserpage.bchange14') parentEpml.request('showSnackBar', `${err4string}`) @@ -4989,13 +4942,13 @@ class WebBrowser extends LitElement { } async deleteCurrentResource() { - if (this.followedNames.indexOf(this.name) != -1) { + if (this.followedNames.indexOf(this.name) !== -1) { // Following name - so deleting won't work let err5string = get('browserpage.bchange15') parentEpml.request('showSnackBar', `${err5string}`) return } - let identifier = (this.identifier == null || this.identifier.length == 0) ? 'default' : this.identifier + let identifier = (this.identifier == null || this.identifier.length === 0) ? 'default' : this.identifier let ret = await parentEpml.request('apiCall', { url: `/arbitrary/resource/${this.service}/${this.name}/${identifier}?apiKey=${this.getApiKey()}`, method: 'DELETE' diff --git a/plugins/plugins/utils/classes.js b/plugins/plugins/utils/classes.js index 605f28b8..751c7194 100644 --- a/plugins/plugins/utils/classes.js +++ b/plugins/plugins/utils/classes.js @@ -1105,6 +1105,19 @@ export const publishData = async ({ } } +export async function getNameInfo(address) { + 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 response = await fetch(`${nodeUrl}/names/address/` + address) + const nameData = await response.json() + + if (nameData.length > 0) { + return nameData[0].name + } else { + return "" + } +} + export const getPublishesFromAdmins = async (admins, groupId) => { const queryString = admins.map((name) => `name=${name}`).join("&") const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] @@ -1113,7 +1126,7 @@ export const getPublishesFromAdmins = async (admins, groupId) => { const response = await fetch(url) if (!response.ok) { - consoöe.error("network error") + console.error("network error") return false } @@ -1178,7 +1191,7 @@ export const getPublishesFromAdminsAdminSpace = async (admins, groupId) => { const response = await fetch(url) if (!response.ok) { - consoöe.error("network error") + console.error("network error") return false }