Socket
Socket
Sign inDemoInstall

@cryptoscamdb/web

Package Overview
Dependencies
Maintainers
2
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cryptoscamdb/web - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

5

package.json
{
"name": "@cryptoscamdb/web",
"version": "0.2.0",
"version": "0.3.0",
"description": "Keeping track of all current cryptocurrency scams in an open-source database",

@@ -67,2 +67,3 @@ "keywords": [

"request": "^2.87.0",
"request-promise-native": "^1.0.5",
"serialijse": "^0.1.3",

@@ -83,3 +84,3 @@ "ts-node": "^7.0.1",

"husky": "^1.0.1",
"lint-staged": "^7.3.0",
"lint-staged": "^8.0.0",
"nodemon": "^1.18.4",

@@ -86,0 +87,0 @@ "prettier": "^1.14.3",

388

src/app.ts
'use strict';
import * as Debug from 'debug';
import { fork } from 'child_process';
import * as express from 'express';
import * as path from 'path';
import config from './utils/config';
import writeConfig from './utils/writeConfig';
import * as fs from 'fs';
import * as url from 'url';
import * as helmet from 'helmet';
import * as db from './utils/db';
import * as github from './utils/github';
import config from './utils/config';
import writeConfig from './utils/writeConfig';
import router from './utils/router';
import * as isIpPrivate from 'private-ip';
import * as checkForPhishing from 'eth-phishing-detect';
import * as dateFormat from 'dateformat';
import createDictionary from '@cryptoscamdb/array-object-dictionary';
import { getGoogleSafeBrowsing, getURLScan, getVirusTotal } from './utils/lookup';
import * as request from 'request-promise-native';

@@ -18,31 +21,3 @@ const debug = Debug('app');

export const update = async (): Promise<void> => {
/* Create and write to cache.db */
debug('Spawning update process...');
const updateProcess = fork(path.join(__dirname, 'scripts/update.ts'));
debug('Writing to cache.db');
updateProcess.on('message', data => db.write(data.url, data));
/* After db is initially written, write the cache.db every cacheRenewCheck-defined period */
updateProcess.on('exit', () => {
debug(
'UpdateProcess completed - Next run is in ' +
config.interval.cacheRenewCheck / 1000 +
' seconds.'
);
setTimeout(() => {
this.update();
}, config.interval.cacheRenewCheck);
});
};
export const serve = async (electronApp?: any): Promise<void> => {
/* Download datafiles if they aren't found yet */
if (!fs.existsSync('data')) {
await github.pullRaw();
}
/* Initiate database */
await db.init();
export const serve = async (): Promise<void> => {
/* Allow both JSON and URL encoded bodies */

@@ -59,5 +34,2 @@ app.use(express.json());

app.set('views', path.join(__dirname, 'views/pages'));
app.locals.environment = process.env.NODE_ENV;
app.locals.announcement = config.announcement;
app.locals.hasSlackWebhook = typeof config.apiKeys.Slack_Webhook === 'string';

@@ -92,16 +64,332 @@ /* Compress pages */

await writeConfig(req.body);
if (electronApp) {
electronApp.relaunch();
electronApp.exit();
} else {
res.render('config', { production: false, done: true });
res.render('config', { production: false, done: true });
}
next();
});
/* Homepage */
app.get('/(/|index.html)?', (req, res) => res.render('index'));
/* FAQ page */
app.get('/faq/', (req, res) => res.render('faq'));
/* API documentation page */
app.get('/api/', (req, res) => res.render('api'));
/* Report pages */
app.get('/report/', (req, res) => res.render('report'));
app.get('/report/domain/:domain?', (req, res) =>
res.render('report', {
domain: req.params.domain || true
})
);
app.get('/report/address/:address?', (req, res) =>
res.render('report', {
address: req.params.address || true
})
);
/* IP pages */
app.get('/ip/:ip', async (req, res) => {
await res.render('ip', {
ip: req.params.ip,
isPrivate: isIpPrivate(req.params.ip),
related:
(await request('https://api.cryptoscamdb.org/v1/ips', { json: true })).result[
req.params.ip
] || []
});
});
/* Address pages */
app.get('/address/:address', async (req, res) => {
const addresses = (await request('https://api.cryptoscamdb.org/v1/addresses', {
json: true
})).result;
const whitelistAddresses = createDictionary(
(await request('https://api.cryptoscamdb.org/v1/verified', { json: true })).result
).addresses;
if (whitelistAddresses[req.params.address]) {
res.render('address', {
address: req.params.address,
related: whitelistAddresses[req.params.address],
type: 'verified'
});
} else if (addresses[req.params.address]) {
res.render('address', {
address: req.params.address,
related: addresses[req.params.address] || [],
type: 'scam'
});
} else {
res.render('address', {
address: req.params.address,
related: addresses[req.params.address] || [],
type: 'neutral'
});
}
});
/* Scams index */
app.get('/scams/:page?/:sorting?/', async (req, res) => {
const fullScams = (await request('https://api.cryptoscamdb.org/v1/scams', {
json: true
})).result.map(scam => {
scam.hostname = url.parse(scam.url).hostname;
return scam;
});
const fullAddresses = (await request('https://api.cryptoscamdb.org/v1/addresses', {
json: true
})).result;
const MAX_RESULTS_PER_PAGE = 30;
const scamList = [];
let scams = [...fullScams].reverse();
let index = [0, MAX_RESULTS_PER_PAGE];
if (
req.params.page &&
req.params.page !== 'all' &&
(!isFinite(parseInt(req.params.page, 10)) ||
isNaN(parseInt(req.params.page, 10)) ||
parseInt(req.params.page, 10) < 1)
) {
res.status(404).render('404');
} else {
if (req.params.sorting === 'oldest') {
scams = fullScams;
} else if (req.params.sorting === 'status') {
scams = [...fullScams].sort((a, b) =>
(a.status || '').localeCompare(b.status || '')
);
} else if (req.params.sorting === 'category') {
scams = [...fullScams].sort((a, b) =>
(a.category || '').localeCompare(b.category || '')
);
} else if (req.params.sorting === 'subcategory') {
scams = [...fullScams].sort((a, b) =>
(a.subcategory || '').localeCompare(b.subcategory || '')
);
} else if (req.params.sorting === 'name') {
scams = [...fullScams].sort((a, b) =>
a.getHostname().localeCompare(b.getHostname())
);
}
if (req.params.page === 'all') {
index = [0, scams.length - 1];
} else if (req.params.page) {
index = [
(req.params.page - 1) * MAX_RESULTS_PER_PAGE,
req.params.page * MAX_RESULTS_PER_PAGE
];
}
for (let i = index[0]; i <= index[1]; i++) {
if (scams.hasOwnProperty(i) === false) {
continue;
}
scamList.push(scams[i]);
}
res.render('scams', {
page: req.params.page,
sorting: req.params.sorting,
total: scams.length.toLocaleString('en-US'),
active: Object.keys(
scams.filter(scam => scam.status === 'Active')
).length.toLocaleString('en-US'),
total_addresses: Object.keys(fullAddresses).length.toLocaleString('en-US'),
inactive: Object.keys(
scams.filter(scam => scam.status === 'Inactive')
).length.toLocaleString('en-US'),
scams: scamList,
MAX_RESULTS_PER_PAGE,
scamsLength: scams.length
});
}
});
/* Coin pages */
app.get('/coin/:coin/:page?/:sorting?/', async (req, res) => {
const MAX_RESULTS_PER_PAGE = 30;
const scamList = [];
const fullScams = (await request('https://api.cryptoscamdb.org/v1/scams', {
json: true
})).result.map(scam => {
scam.hostname = url.parse(scam.url).hostname;
if (scam.coin) {
scam.coin = scam.coin.toLowerCase();
}
return scam;
});
const fullAddresses = (await request('https://api.cryptoscamdb.org/v1/addresses', {
json: true
})).result;
let scams = [...fullScams.filter(scam => scam.coin === req.params.coin)].reverse();
let index = [0, MAX_RESULTS_PER_PAGE];
if (
req.params.page &&
req.params.page !== 'all' &&
(!isFinite(parseInt(req.params.page, 10)) ||
isNaN(parseInt(req.params.page, 10)) ||
parseInt(req.params.page, 10) < 1)
) {
res.status(404).render('404');
} else {
next();
if (req.params.sorting === 'oldest') {
scams = fullScams.filter(scam => scam.coin === req.params.coin);
} else if (req.params.sorting === 'status') {
scams = [...fullScams.filter(scam => scam.coin === req.params.coin)].sort((a, b) =>
(a.status || '').localeCompare(b.status || '')
);
} else if (req.params.sorting === 'category') {
scams = [...fullScams.filter(scam => scam.coin === req.params.coin)].sort((a, b) =>
(a.category || '').localeCompare(b.category || '')
);
} else if (req.params.sorting === 'subcategory') {
scams = [...fullScams.filter(scam => scam.coin === req.params.coin)].sort((a, b) =>
(a.subcategory || '').localeCompare(b.subcategory || '')
);
} else if (req.params.sorting === 'name') {
scams = [...fullScams.filter(scam => scam.coin === req.params.coin)].sort((a, b) =>
a.getHostname().localeCompare(b.getHostname())
);
}
if (req.params.page === 'all') {
index = [0, scams.length - 1];
} else if (req.params.page) {
index = [
(req.params.page - 1) * MAX_RESULTS_PER_PAGE,
req.params.page * MAX_RESULTS_PER_PAGE
];
}
for (let i = index[0]; i <= index[1]; i++) {
if (scams.hasOwnProperty(i) === false) {
continue;
}
scamList.push(scams[i]);
}
res.render('coin', {
coin: req.params.coin,
page: req.params.page,
sorting: req.params.sorting,
total: scams.length.toLocaleString('en-US'),
active: Object.keys(
scams.filter(scam => scam.status === 'Active')
).length.toLocaleString('en-US'),
total_addresses: Object.keys(fullAddresses)
.filter(address =>
fullAddresses[address].some(scam => scam.coin === req.params.coin)
)
.length.toLocaleString('en-US'),
inactive: Object.keys(
scams.filter(scam => scam.status === 'Inactive')
).length.toLocaleString('en-US'),
scams: scamList,
MAX_RESULTS_PER_PAGE,
scamsLength: scams.length
});
}
});
/* Serve all other routes (see src/utils/router.js) */
app.use(router);
/* Domain pages */
app.get('/domain/:url', async (req, res) => {
const startTime = Date.now();
const { hostname } = url.parse(
'http://' + req.params.url.replace('http://', '').replace('https://')
);
const fullScams = (await request('https://api.cryptoscamdb.org/v1/scams', {
json: true
})).result.map(scam => {
scam.hostname = url.parse(scam.url).hostname;
return scam;
});
const fullVerified = (await request('https://api.cryptoscamdb.org/v1/verified', {
json: true
})).result.map(scam => {
scam.hostname = url.parse(scam.url).hostname;
return scam;
});
const scamEntry = fullScams.find(scam => scam.hostname === hostname);
const verifiedEntry = fullVerified.find(verified => verified.hostname === hostname);
const urlScan = await getURLScan(hostname);
const domainurl = 'https://cryptoscamdb.org/domain/' + hostname;
let googleSafeBrowsing;
let virusTotal;
if ((scamEntry || !verifiedEntry) && config.apiKeys.Google_SafeBrowsing) {
googleSafeBrowsing = await getGoogleSafeBrowsing(hostname);
}
if ((scamEntry || !verifiedEntry) && config.apiKeys.VirusTotal) {
virusTotal = await getVirusTotal(hostname);
}
if (verifiedEntry) {
res.render('domain', {
type: 'verified',
result: verifiedEntry,
domain: hostname,
urlScan,
metamask: false,
googleSafeBrowsing,
virusTotal,
startTime,
dateFormat,
domainurl
});
} else if (scamEntry) {
res.render('domain', {
type: 'scam',
result: scamEntry,
domain: hostname,
urlScan,
metamask: checkForPhishing(hostname),
googleSafeBrowsing,
virusTotal,
startTime,
dateFormat,
abuseReport: (await request(
'https://api.cryptoscamdb.org/v1/abusereport/' + encodeURIComponent(hostname),
{ json: true }
)).result,
domainurl
});
} else {
res.render('domain', {
type: 'neutral',
domain: hostname,
result: false,
urlScan,
metamask: checkForPhishing(hostname),
googleSafeBrowsing,
virusTotal,
addresses: [],
startTime,
domainurl
});
}
});
/* Verified pages */
app.get('/verified/', async (req, res) =>
res.render('verified', {
featured: (await request('https://api.cryptoscamdb.org/v1/featured', {
json: true
})).result.sort((a, b) => a.name.localeCompare(b.name))
})
);
/* Safe redirect pages */
app.get('/redirect/:url', (req, res) => res.render('redirect', { url: req.params.url }));
/* Serve all other pages as 404 */

@@ -112,10 +400,2 @@ app.get('*', (req, res) => res.status(404).render('404'));

app.listen(config.port, () => debug('Content served on http://localhost:%s', config.port));
/* Update scams after 100ms timeout (to process async) */
setTimeout(() => this.update(), 100);
/* If auto pulling from Github is enabled; schedule timer */
if (config.autoPull.enabled) {
setInterval(github.pullData, config.autoPull.interval);
}
};

@@ -122,0 +402,0 @@

window.addEventListener("load", function() {
$.getJSON("https://api.etherscan.io/api?module=account&action=balance&tag=latest&address=" + $("h1").html(), function(data) {
$("#balance").html((Math.round(data.result / (10e17) * 100000) / 100000) + ' ETH');
$.getJSON("https://api.coinmarketcap.com/v1/ticker/ethereum/?convert=USD", function(val) {
$("#value").html((Math.round((data.result / (10e17)) * val[0].price_usd * 100) / 100).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + "$ (" + Math.round(val[0].price_usd * 100) / 100 + " USD/ETH)");
$.getJSON("https://api.cryptoscamdb.org/v1/check/" + $("h1").html(), function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/balance/" + data.coin + "/" + $("h1").html(), function(val) {
$("#balance").html(val.balance.toFixed(2) + " " + data.coin.toUpperCase());
$("#value").html("$"+ val.usdvalue.toFixed(2) + " ($" + (val.usdvalue / val.balance).toFixed(2) + " USD/" + data.coin.toUpperCase() + ")");
$("#explorer").attr("href", val.blockexplorer);
});
});
});
window.addEventListener("load", function() {
$.getJSON("/api/v1/check/0xDaa29859836D97C810c7F9D350D4A1B3E8CafC9a",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/check/0xDaa29859836D97C810c7F9D350D4A1B3E8CafC9a",function(data) {
data = JSON.stringify(data, null, 2);

@@ -8,3 +8,3 @@ $("#check_loader").remove();

});
$.getJSON("/api/v1/scams/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/scams/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -15,3 +15,3 @@ $("#scams_loader").remove();

});
$.getJSON("/api/v1/addresses/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/addresses/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -22,3 +22,3 @@ $("#addresses_loader").remove();

});
$.getJSON("/api/v1/ips/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/ips/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -29,3 +29,3 @@ $("#ips_loader").remove();

});
$.getJSON("/api/v1/verified/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/verified/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -36,3 +36,3 @@ $("#verified_loader").remove();

});
$.getJSON("/api/v1/blacklist/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/blacklist/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -43,3 +43,3 @@ $("#blacklist_loader").remove();

});
$.getJSON("/api/v1/whitelist/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/whitelist/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -50,3 +50,3 @@ $("#whitelist_loader").remove();

});
$.getJSON("/api/v1/inactives/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/inactives/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -57,3 +57,3 @@ $("#inactives_loader").remove();

});
$.getJSON("/api/v1/actives/",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/actives/",function(data) {
data = JSON.stringify(data, null, 2);

@@ -64,3 +64,3 @@ $("#actives_loader").remove();

});
$.getJSON("/api/v1/abusereport/changellyli.com",function(data) {
$.getJSON("https://api.cryptoscamdb.org/v1/abusereport/changellyli.com",function(data) {
data = JSON.stringify(data, null, 2);

@@ -67,0 +67,0 @@ $("#abusereport_loader").remove();

window.addEventListener("load", function() {
$("#github").click(function() {
window.open('https://github.com/CryptoScamDB/cryptoscamdb.org');
window.open('https://github.com/CryptoScamDB');
});

@@ -5,0 +5,0 @@ $("#scams").click(function() {

@@ -7,3 +7,3 @@ var reportType;

$(".loading").fadeIn('', function() {
$.post(reportEndpoint, {
$.post("https://api.cryptoscamdb.org/v1/report/", {
reportType: reportType,

@@ -10,0 +10,0 @@ args: args

@@ -6,3 +6,3 @@ var args = {};

$(".loading").fadeIn('', function() {
$.post(reportEndpoint, {
$.post("https://api.cryptoscamdb.org/v1/report/", {
reportType: 'generalAddressReport',

@@ -9,0 +9,0 @@ args: args

@@ -7,3 +7,3 @@ var reportType;

$(".loading").fadeIn('', function() {
$.post(reportEndpoint, {
$.post("https://api.cryptoscamdb.org/v1/report/", {
reportType: 'generalDomainReport',

@@ -10,0 +10,0 @@ args: args

@@ -12,4 +12,4 @@ function hideEverything() {

console.log('button click recorded')
$.getJSON("/api/v1/check/" + encodeURIComponent($("input").val().toLowerCase().replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0]), function(result) {
if (result.result === 'verified') {
$.getJSON("https://api.cryptoscamdb.org/v1/check/" + encodeURIComponent($("input").val().toLowerCase().replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0]), function(result) {
if (result.result.status === 'verified') {
hideEverything();

@@ -21,6 +21,6 @@ var strLinkVerified = '';

$("#verified").css('display', 'flex');
} else if (result.result === 'neutral') {
} else if (result.result.status === 'neutral') {
hideEverything();
var strLinkNeutral = '';
if(result.type === 'address'){
if(result.result.type === 'address'){
$("#neutralmessage").html('<b>' + encodeURI($("input").val().toLowerCase().replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0]) + '</b> wasn\'t a recognized ETH address.');

@@ -37,3 +37,3 @@ strLinkNeutral = '<a id="details" href="https://etherscan.io/address/' + encodeURI($("input").val()) + '">View this address on Etherscan <i class="chevron right small icon"></i></a>';

}
} else if (result.result === 'whitelisted') {
} else if (result.result.status === 'whitelisted') {
hideEverything();

@@ -45,14 +45,14 @@ var strLinkWhitelisted = '';

$("#verified").css('display', 'flex');
} else if (result.result === 'blocked') {
} else if (result.result.status === 'blocked') {
hideEverything();
blocked = true;
var strLinkBlocked = '';
if (result.type === 'domain' && 'category' in result.entries[0]) {
$("#blacklistmessage").html('<b>' + encodeURI($("input").val().toLowerCase().replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0]) + '</b> was put on the blacklist for ' + result.entries[0].category.toLowerCase() + '.');
if (result.result.type === 'domain' && 'category' in result.result.entries[0]) {
$("#blacklistmessage").html('<b>' + encodeURI($("input").val().toLowerCase().replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0]) + '</b> was put on the blacklist for ' + result.result.entries[0].category.toLowerCase() + '.');
strLinkBlocked = '<a id="details" href="/domain/' + encodeURI($("input").val()) + '">Details on this domain <i class="chevron right small icon"></i></a>';
} else if(result.type === 'address') {
$("#blacklistmessage").html('<b>' + encodeURI($("input").val().toLowerCase()) + ' was put on the blacklist and is associated with '+ result.entries.length +' blocked domain(s).');
} else if(result.result.type === 'address') {
$("#blacklistmessage").html('<b>' + encodeURI($("input").val().toLowerCase()) + ' was put on the blacklist and is associated with '+ result.result.entries.length +' blocked domain(s).');
strLinkBlocked = '<a id="details" href="/address/' + encodeURI($("input").val()) + '">Details on this address <i class="chevron right small icon"></i></a>';
} else if(result.type === 'ip') {
$("#blacklistmessage").html('<b>' + encodeURI($("input").val().toLowerCase().replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0]) + '</b> was put on the blacklist and is associated with '+ result.entries.length +' blocked domain(s)');
} else if(result.result.type === 'ip') {
$("#blacklistmessage").html('<b>' + encodeURI($("input").val().toLowerCase().replace('http://','').replace('https://','').replace('www.','').split(/[/?#]/)[0]) + '</b> was put on the blacklist and is associated with '+ result.result.entries.length +' blocked domain(s)');
strLink = '<a id="details" href="/ip/' + encodeURI($("input").val()) + '">Details on this domain <i class="chevron right small icon"></i></a>';

@@ -59,0 +59,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc