From 15cd5253390a0b5800e5ccfeff8e3c9f6f8241d8 Mon Sep 17 00:00:00 2001 From: Jarred Date: Tue, 20 Dec 2022 10:48:19 -0600 Subject: [PATCH] Higher quality code & Tests file --- assets/js/xrp-ledger-toml-checker-test.js | 164 ++++++++++++++++++++++ assets/js/xrp-ledger-toml-checker.js | 61 ++++---- 2 files changed, 199 insertions(+), 26 deletions(-) create mode 100644 assets/js/xrp-ledger-toml-checker-test.js diff --git a/assets/js/xrp-ledger-toml-checker-test.js b/assets/js/xrp-ledger-toml-checker-test.js new file mode 100644 index 0000000000..7d86e7f594 --- /dev/null +++ b/assets/js/xrp-ledger-toml-checker-test.js @@ -0,0 +1,164 @@ +// This code takes in a wallet address, checks the domain field, then gets the TOML info to verify the domains ownership. +// This is runnable in NODE JS for easier testing, and works the same as the code in xrp-ledger-toml-checker.js +const WebSocket = require('ws'); +const https = require('https'); +const TOML = require('../vendor/iarna-toml-parse'); + +const TOML_PATH = "/.well-known/xrp-ledger.toml" +const TIPS = 'Check if the file is actually hosted at the URL above, check your server\'s HTTPS settings and certificate, and make sure your server provides the required CORS header.\n' +const TIPS_1 = 'Make sure you are entering a valid XRP address.\n' +const TIPS_2 = 'Make sure the wallet address has the domain field.\n' + +const ACCOUNT_FIELDS = [ + "address", + "network", + "desc" +] + +// set 'wallet' to any of these test wallets +const works2 = 'rSTAYKxF2K77ZLZ8GoAwTqPGaphAqMyXV' +const works = 'r4MPhp7NeayAohgEd8FWSUV6eR2nLGwDX3' +const no_toml2 = 'rV64miFA53xbWS3x9A6nRnzxMqLHN1t2h' +const no_toml = 'rsoLo2S1kiGeCcn6hCUXVrCpGMWLrRrLZz' +const no_domain = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh' +const wallet = no_toml +let socket; + + +function fetch_file_1(domain) { + // NODE AJAX equivalent + const url = "https://" + domain + TOML_PATH + console.log('Checking ' + url + '\n') + + https.get(url, (resp) => { + let data = ''; + resp.on('data', (chunk) => { + data += chunk; + }); + resp.on('end', () => { + if (data != '') { + console.log('TOML Found\n'); + parse_xrpl_toml_1(data, domain) + } else { + console.log(TIPS) + process.exit() + } + }); + }).on("error", (err) => { + console.log("Error: " + err.message); + process.exit() + }); +} + +function fetch_wallet_1() { + console.log('Checking domain of wallet...\n') + + const url = "wss://xrplcluster.com" + if (typeof socket !== "undefined" && socket.readyState < 2) { + socket.close() + } + const data = { + "command": "account_info", + "account": wallet, + } + socket = new WebSocket(url) + socket.addEventListener('message', (event) => { + let data; + try { + data = JSON.parse(event.data) + if (data.status === 'success') { + if (data.result.account_data.Domain) { + try { + decode_hex_1(data.result.account_data.Domain) + } catch { + console.log('error decoding domain field: ' + data.result.account_data.Domain) + } + } else { + console.log(TIPS_2) + process.exit() + } + } else { + console.log(TIPS_1) + } + } catch (e) { + console.log(e) + process.exit() + } + }) + socket.addEventListener('open', () => { + socket.send(JSON.stringify(data)) + }) +} + +async function parse_xrpl_toml_1(data, domain) { + let parsed + console.log("Parsing TOML data...\n") + try { + parsed = TOML(data) + } catch (e) { + console.log('TOML ERROR: Wallet can not be verified\n') + process.exit() + } + if (parsed.hasOwnProperty("METADATA")) { + console.log("Metadata section: ") + if (Array.isArray(parsed.METADATA)) { + console.log("Wrong type - should be table\n") + } else { + console.log("Found \n") + if (parsed.METADATA.modified) { + console.log("Modified date: ") + try { + console.log(parsed.METADATA.modified.toISOString() + '\n') + } catch (e) { + console.log("INVALID\n") + } + } + } + } + + async function list_entries_1(list, fields) { + let found = false; + for (i = 0; i < list.length; i++) { + let entry = list[i] + for (j = 0; j < fields.length; j++) { + let fieldname = fields[j] + if (fieldname == 'address' && entry[fieldname] !== undefined) { + if (entry[fieldname] === wallet) { + console.log('MATCH: ' + entry[fieldname] + ' *\n') + found = true; + } else { + console.log('NO_MATCH: ' + entry[fieldname] + '\n') + } + } + } + } + if (found) { + console.log('WALLET DOMAIN VERIFIED\n') + } else { + console.log('WALLET NOT VERIFIED. WALLET NOT PRESENT IN TOML FILE\n') + } + process.exit() + } + if (parsed.ACCOUNTS) { + if (!Array.isArray(parsed.ACCOUNTS)) { + console.log("Wrong type- should be table-array") + process.exit() + } else { + list_entries_1(parsed.ACCOUNTS, ACCOUNT_FIELDS) + } + } +} + +function decode_hex_1(hex) { + let str = ''; + for (let i = 0; i < hex.length; i += 2) { + str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)) + } + console.log('Domain decoded: ' + str + '\n') + fetch_file_1(str) +} + + + +// RUNS CODE. Edit 'wallet' CONST at top of file to change wallet. +fetch_wallet_1() \ No newline at end of file diff --git a/assets/js/xrp-ledger-toml-checker.js b/assets/js/xrp-ledger-toml-checker.js index 7a2ad35451..53fdc584b4 100644 --- a/assets/js/xrp-ledger-toml-checker.js +++ b/assets/js/xrp-ledger-toml-checker.js @@ -97,8 +97,6 @@ async function parse_xrpl_toml(data, domain) { return } - console.log(parsed) - if (parsed.hasOwnProperty("METADATA")) { const metadata_type = makeLogEntry("Metadata section: ") if (Array.isArray(parsed.METADATA)) { @@ -257,6 +255,9 @@ function handle_submit(event) { } // ------------------------------------------ DOMAIN VERIFICATION VIA ACCOUNT BELOW ------------------------------------------ +let wallet; +let socket; + function makeLogEntry_1(text, raw) { let log @@ -279,7 +280,7 @@ function fetch_file_1(domain) { dataType: 'text', success: function(data) { log.resolve('FOUND').addClass(CLASS_GOOD) - parse_xrpl_toml_1(data, domain) + parse_xrpl_toml_1(data) }, error: function(jqxhr, status, error) { switch (status) { @@ -300,9 +301,8 @@ function fetch_file_1(domain) { }) } -let socket; function fetch_wallet_1() { - const wallet = $('#verify-domain').val() + wallet = $('#verify-domain').val() const checking_log = makeLogEntry_1('Checking domain of wallet') const url = "wss://xrplcluster.com" @@ -310,12 +310,8 @@ function fetch_wallet_1() { socket.close() } const data = { - "id": 2, "command": "account_info", "account": wallet, - "strict": true, - "ledger_index": "current", - "queue": true } socket = new WebSocket(url) socket.addEventListener('message', (event) => { @@ -323,22 +319,30 @@ function fetch_wallet_1() { try { data = JSON.parse(event.data) if (data.status === 'success') { - decode_hex_1(data.result.account_data.Domain) - checking_log.resolve('SUCCESS').addClass(CLASS_GOOD) + if (data.result.account_data.Domain) { + try { + checking_log.resolve('SUCCESS').addClass(CLASS_GOOD) + decode_hex_1(data.result.account_data.Domain) + } catch { + checking_log.resolve('ERROR').addClass(CLASS_BAD).after('

Error decoding domain field: ' + data.result.account_data.Domain + '

') + } + } else { + checking_log.resolve('ERROR').addClass(CLASS_BAD).after(TIPS_2) + } + } else { checking_log.resolve('ERROR').addClass(CLASS_BAD).after(TIPS_1) } } catch { - checking_log.resolve('ERROR').addClass(CLASS_BAD).after(TIPS_2) return false } }) - socket.addEventListener('open', (event) => { + socket.addEventListener('open', () => { socket.send(JSON.stringify(data)) }) } -async function parse_xrpl_toml_1(data, domain) { +async function parse_xrpl_toml_1(data) { let parsed let log1 = makeLogEntry_1("Parsing TOML data...") try { @@ -368,33 +372,38 @@ async function parse_xrpl_toml_1(data, domain) { } async function list_entries_1(name, list, fields) { + let found = false; let list_wrap = $("

"+name+"

") let list_ol = $("
    ").appendTo(list_wrap) for (i=0; i").appendTo(list_ol) + let entry_wrap = $("
  1. ").appendTo(list_ol) + let entry_def = $("
      ").appendTo(entry_wrap) let entry = list[i] for (j=0; j"+fieldname+": ").appendTo(entry_def) - $(" ").text(entry[fieldname]).appendTo(field_def) - entry_def.append('
    • Domain Validated
    • ') + if (entry[fieldname] !== undefined) { + let field_def = $("
    • "+fieldname+": ").appendTo(entry_def) + $(" ").text(entry[fieldname]).appendTo(field_def) } } + if (entry['address'] === wallet) { + entry_def.append('
    • Domain Validated
    • ') + found=true; + } } + makeLogEntry_1(list_wrap, true) + if(found) { + makeLogEntry_1('Account has been found in TOML file and validated.').resolve('DOMAIN VALIDATED ').addClass(CLASS_GOOD) + } else { + makeLogEntry_1('Account not found in TOML file. Domain can not be verified.').resolve('ERROR').addClass(CLASS_BAD) + } } if (parsed.ACCOUNTS) { if (!Array.isArray(parsed.ACCOUNTS)) { makeLogEntry_1("Accounts:").resolve("Wrong type - should be table-array").addClass(CLASS_BAD) } else { - list_entries_1("Accounts:", parsed.ACCOUNTS, ACCOUNT_FIELDS, async function(acct) { - if (acct.address === undefined) {return undefined} - let net - if (acct.network === undefined) { net = "main" } else { net = acct.network } - return await validate_address_domain_on_net(acct.address, domain, net) - }) + list_entries_1("Accounts:", parsed.ACCOUNTS, ACCOUNT_FIELDS) } } }