From 40b5787493711f6ecdc37e8b8098331d4160405a Mon Sep 17 00:00:00 2001 From: joeuhren <46763106+joeuhren@users.noreply.github.com> Date: Wed, 23 Dec 2020 18:40:10 -0700 Subject: [PATCH] Claim address updates -Claimed addresses now replace actual wallet addresses across all pages of the site -Add new claim_address setting to enable/disable claiming of addresses -Add ability to un-claim an address by signing a blank message --- README.md | 1 + app.js | 4 +- lib/database.js | 122 +++++++++++++++++++++++++++++---- lib/settings.js | 1 + routes/index.js | 59 +++++++++++----- settings.json.template | 3 +- views/address.pug | 40 ++++++----- views/claim_address.pug | 22 +++--- views/includes/rl_balance.pug | 5 +- views/includes/rl_labels.pug | 6 +- views/includes/rl_received.pug | 5 +- views/tx.pug | 15 +++- 12 files changed, 212 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 495ba27..a85025c 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ This project is a fork of [Ciquidus Explorer](https://github.com/suprnurd/ciquid - flag-icon-css v3.5.0 ([https://github.com/lipis/flag-icon-css](https://github.com/lipis/flag-icon-css)) - Mobile-friendly - Sass support +- Claim address with bad word filter support (Allows anyone to set custom display names for wallet addresses that they own) - Custom rpc/api command support which increases blockchain compatibility. Supported cmds: - **getnetworkhashps:** Returns the estimated network hashes per second - **getmininginfo:** Returns a json object containing mining-related information diff --git a/app.js b/app.js index 82d4cbb..fa07873 100644 --- a/app.js +++ b/app.js @@ -283,9 +283,9 @@ app.post('/address/:hash/claim', function(req, res) { // initialize the bad-words filter var bad_word_lib = require('bad-words'); var bad_word_filter = new bad_word_lib(); - + // clean the message (Display name) of bad words - var message = bad_word_filter.clean(req.body.message); + var message = (req.body.message == null || req.body.message == '' ? '' : bad_word_filter.clean(req.body.message)); // check if the message was filtered if (message == req.body.message) { diff --git a/lib/database.js b/lib/database.js index 3c29ec0..a5764e3 100644 --- a/lib/database.js +++ b/lib/database.js @@ -250,13 +250,50 @@ module.exports = { return fs.existsSync('./tmp/show_sync_message.tmp'); }, - update_label: function(hash, message, cb){ - find_address(hash, false, function(address){ - if (address){ - Address.updateOne({a_id:hash}, { - name: message, - }, function(){ - return cb(); + update_label: function(hash, message, cb) { + find_address(hash, false, function(address) { + if (address) { + Address.updateOne({a_id: hash}, { + name: message + }, function() { + // ensure that if this address exists in the richlist that it displays the new alias + module.exports.get_richlist(settings.coin, function(richlist) { + var updated = false; + // loop through received addresses + for (r = 0; r < richlist.received.length; r++) { + // check if this is the correct address + if (richlist.received[r].a_id == hash) { + // update the claim name + richlist.received[r]['name'] = message; + // mark as updated + updated = true; + } + } + // loop through balance addresses + for (b = 0; b < richlist.balance.length; b++) { + // check if this is the correct address + if (richlist.balance[b].a_id == hash) { + // update the claim name + richlist.balance[b]['name'] = message; + // mark as updated + updated = true; + } + } + // check if the address was updated in the richlist + if (updated) { + // save the richlist back to collection + Richlist.updateOne({coin: settings.coin}, { + received: richlist.received, + balance: richlist.balance + }, function() { + // finished updating the claim label + return cb(); + }); + } else { + // finished updating the claim label + return cb(); + } + }); }); } }); @@ -320,7 +357,8 @@ module.exports = { return cb(richlist); }); }, - //property: 'received' or 'balance' + + // 'list' variable can be either 'received' or 'balance' update_richlist: function(list, cb){ // Create the burn address array so that we omit burned coins from the rich list var oBurnAddresses = []; @@ -330,18 +368,20 @@ module.exports = { // always omit the private address from the richlist oBurnAddresses.push("private_tx"); - if(list == 'received') { - Address.find({a_id: { $nin: oBurnAddresses }}, 'a_id balance received').sort({received: 'desc'}).limit(100).exec(function(err, addresses){ + if (list == 'received') { + // Update 'received' richlist data + Address.find({a_id: { $nin: oBurnAddresses }}, 'a_id name balance received').sort({received: 'desc'}).limit(100).exec(function(err, addresses) { Richlist.updateOne({coin: settings.coin}, { - received: addresses, + received: addresses }, function() { return cb(); }); }); - } else { //balance - Address.find({a_id: { $nin: oBurnAddresses }}, 'a_id balance received').sort({balance: 'desc'}).limit(100).exec(function(err, addresses){ + } else { + // Update 'balance' richlist data + Address.find({a_id: { $nin: oBurnAddresses }}, 'a_id name balance received').sort({balance: 'desc'}).limit(100).exec(function(err, addresses) { Richlist.updateOne({coin: settings.coin}, { - balance: addresses, + balance: addresses }, function() { return cb(); }); @@ -950,5 +990,59 @@ module.exports = { }); }, + populate_claim_address_names: function(tx, cb) { + var addresses = []; + + // loop through vin addresses + tx.vin.forEach(function (vin) { + // check if this address already exists + if (addresses.indexOf(vin.addresses) == -1) { + // add address to array + addresses.push(vin.addresses); + } + }); + + // loop through vout addresses + tx.vout.forEach(function (vout) { + // check if this address already exists + if (addresses.indexOf(vout.addresses) == -1) { + // add address to array + addresses.push(vout.addresses); + } + }); + + // loop through address array + lib.syncLoop(addresses.length, function (loop) { + var a = loop.iteration(); + + module.exports.get_address(addresses[a], false, function(address) { + if (address && address.name != null && address.name != '') { + // look for address in vin + for (v = 0; v < tx.vin.length; v++) { + // check if this is the correct address + if (tx.vin[v].addresses == address.a_id) { + // add claim name to array + tx.vin[v]['claim_name'] = address.name; + } + } + + // look for address in vout + for (v = 0; v < tx.vout.length; v++) { + // check if this is the correct address + if (tx.vout[v].addresses == address.a_id) { + // add claim name to array + tx.vout[v]['claim_name'] = address.name; + } + } + } + + loop.next(); + }); + }, function() { + // return modified tx object + return cb(tx); + }); + }, + fs: fs }; \ No newline at end of file diff --git a/lib/settings.js b/lib/settings.js index 5f5945c..c0c6ad6 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -90,6 +90,7 @@ exports.display = { "richlist": true, "movement": true, "network": true, + "claim_address": true, "page_header_bgcolor": "", "page_footer_bgcolor": "", "table_header_bgcolor": "", diff --git a/routes/index.js b/routes/index.js index 5335e04..d037edb 100644 --- a/routes/index.js +++ b/routes/index.js @@ -53,10 +53,15 @@ function route_get_tx(res, txid) { db.get_tx(txid, function(tx) { if (tx) { lib.get_blockcount(function(blockcount) { - res.render('tx', { active: 'tx', tx: tx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + if (settings.display.claim_address) { + db.populate_claim_address_names(tx, function(tx) { + res.render('tx', { active: 'tx', tx: tx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + }); + } else { + res.render('tx', { active: 'tx', tx: tx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + } }); - } - else { + } else { lib.get_rawtransaction(txid, function(rtx) { if (rtx && rtx.txid) { lib.prepare_vin(rtx, function(vin) { @@ -72,7 +77,14 @@ function route_get_tx(res, txid) { blockhash: '-', blockindex: -1, }; - res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount:-1, showSync: db.check_show_sync_message()}); + + if (settings.display.claim_address) { + db.populate_claim_address_names(utx, function(utx) { + res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount:-1, showSync: db.check_show_sync_message()}); + }); + } else { + res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount:-1, showSync: db.check_show_sync_message()}); + } } else { // check if blockheight exists if (!rtx.blockheight && rtx.blockhash) { @@ -90,7 +102,13 @@ function route_get_tx(res, txid) { blockindex: block.height, }; lib.get_blockcount(function(blockcount) { - res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + if (settings.display.claim_address) { + db.populate_claim_address_names(utx, function(utx) { + res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + }); + } else { + res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + } }); } else { // cannot load tx @@ -109,7 +127,13 @@ function route_get_tx(res, txid) { blockindex: rtx.blockheight, }; lib.get_blockcount(function(blockcount) { - res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + if (settings.display.claim_address) { + db.populate_claim_address_names(utx, function(utx) { + res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + }); + } else { + res.render('tx', { active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0), showSync: db.check_show_sync_message()}); + } }); } } @@ -132,22 +156,25 @@ function route_get_index(res, error) { function route_get_address(res, hash, count) { db.get_address(hash, false, function(address) { if (address) { - var txs = []; - res.render('address', { active: 'address', address: address, txs: txs, showSync: db.check_show_sync_message()}); + res.render('address', { active: 'address', address: address, showSync: db.check_show_sync_message()}); } else { route_get_index(res, hash + ' not found'); } }); } -function route_get_claim_form(res, hash){ - db.get_address(hash, false, function(address) { - if (address) { - res.render("claim_address", { active: "address", address: address, showSync: db.check_show_sync_message()}); - } else { - route_get_index(res, hash + ' not found'); - } - }); +function route_get_claim_form(res, hash) { + // check if claiming addresses is enabled + if (settings.display.claim_address) { + db.get_address(hash, false, function(address) { + if (address) + res.render("claim_address", { active: "address", address: address, showSync: db.check_show_sync_message()}); + else + route_get_index(res, hash + ' not found'); + }); + } else { + route_get_address(res, hash, settings.txcount); + } } /* GET home page. */ diff --git a/settings.json.template b/settings.json.template index 43fef32..873eec0 100644 --- a/settings.json.template +++ b/settings.json.template @@ -111,7 +111,8 @@ "search": true, "movement": true, "network": true, - + // Enable/disable the ability for users to claim a wallet address. NOTE: Disabling this feature after addresses have already been claimed will effectively hide the claimed values and restore the original wallet addresses again + "claim_address": true, // page_header_bgcolor: change the background color of the page header // page_footer_bgcolor: change the background color of the page footer // valid options: light, dark, primary, secondary, success, info, warning, danger or leave blank ( "" ) for default colors diff --git a/views/address.pug b/views/address.pug index ffdbdc6..627398d 100644 --- a/views/address.pug +++ b/views/address.pug @@ -10,27 +10,29 @@ block content .col-xs-12.col-md-12 .card.card-default.border-0.card-address-summary.cardSpacer .card-header(style='position:relative;') - strong #{address.a_id} - if settings.labels[address.a_id] - if settings.labels[address.a_id].type - label.d-none.d-sm-block.badge.float-right(class='badge-'+settings.labels[address.a_id].type, style='margin-left:15px;margin-bottom:0;') - =settings.labels[address.a_id].label - if settings.labels[address.a_id].url - a(href=settings.labels[address.a_id].url, target='_blank', alt='Visit site', title='Visit site', data-toggle='tooltip', data-placement='top') - span.fa.fa-question-circle(style='margin-left:5px;') - else - label.d-none.d-sm-block.badge.badge-default.float-right(style='margin-left:15px;margin-bottom:0;') - =settings.labels[address.a_id].label - if settings.labels[address.a_id].url - a(href=settings.labels[address.a_id].url, target='_blank', alt='Visit site', title='Visit site', data-toggle='tooltip', data-placement='top') - span.fa.fa-question-circle(style='margin-left:5px;') + if settings.display.claim_address == false || address.name == null || address.name == '' + strong #{address.a_id} + else + strong #{address.name} + if settings.labels[address.a_id] + if settings.labels[address.a_id].type + label.d-none.d-sm-block.badge.float-right(class='badge-'+settings.labels[address.a_id].type, style='margin-left:15px;margin-bottom:0;') + =settings.labels[address.a_id].label + if settings.labels[address.a_id].url + a(href=settings.labels[address.a_id].url, target='_blank', alt='Visit site', title='Visit site', data-toggle='tooltip', data-placement='top') + span.fa.fa-question-circle(style='margin-left:5px;') else - if address.name !== "" && typeof address.name !== "undefined" - label.badge.badge-pill.float-right.d-none.d-sm-block(style='margin-left:15px;') - =address.name + label.d-none.d-sm-block.badge.badge-default.float-right(style='margin-left:15px;margin-bottom:0;') + =settings.labels[address.a_id].label + if settings.labels[address.a_id].url + a(href=settings.labels[address.a_id].url, target='_blank', alt='Visit site', title='Visit site', data-toggle='tooltip', data-placement='top') + span.fa.fa-question-circle(style='margin-left:5px;') + else if settings.display.claim_address == true + a.badge.badge-pill.float-right.d-none.d-sm-block(href="/address/"+ address.a_id +"/claim" style="font-size:smaller;padding-bottom:0;") + if address.name == null || address.name == '' + =" Is this yours? Claim it now for free!" else - a.badge.badge-pill.float-right.d-none.d-sm-block(href="/address/"+ address.a_id +"/claim" style="font-size:smaller;padding-bottom:0;") - =" Is this yours? Claim it now for free!" + =" Update claimed address" table.table.table-bordered.table-striped.summary-table.mobile-border-right - var theadClasses = []; if settings.display.table_header_bgcolor != null && settings.display.table_header_bgcolor != '' diff --git a/views/claim_address.pug b/views/claim_address.pug index 9a2f0d5..ec7b9df 100644 --- a/views/claim_address.pug +++ b/views/claim_address.pug @@ -6,10 +6,10 @@ block content function displayAsText(str) { return str.replace(//g, '>'); } - function showClaimAlert(claimClass, warnMsg) { + function showClaimAlert(claimClass, warnMsg, removedClaim) { if ($('#claimAlert').length == 0) $('
').insertBefore('#claimForm'); - $('#claimAlert').html('