mirror of https://github.com/embarklabs/embark.git
refactor(ENS): adds a whitelist for ens
Enables only the use of domains in that white list
This commit is contained in:
parent
bae31165dd
commit
d09d410021
|
@ -3,12 +3,16 @@ import {getAccounts, getBlocks, getTransactions, getContracts, getEnsRecordForNa
|
||||||
import {fetchAccounts, fetchBlocks, fetchTransactions, fetchContracts, fetchEnsRecord} from "./index";
|
import {fetchAccounts, fetchBlocks, fetchTransactions, fetchContracts, fetchEnsRecord} from "./index";
|
||||||
import {ELEMENTS_LIMIT} from '../constants';
|
import {ELEMENTS_LIMIT} from '../constants';
|
||||||
|
|
||||||
|
const ENS_WHITELIST = [
|
||||||
|
".eth",
|
||||||
|
".xyz"
|
||||||
|
]; // Putting this here as I can't import from embark's constants
|
||||||
|
|
||||||
export function *searchExplorer(entity, payload) {
|
export function *searchExplorer(entity, payload) {
|
||||||
let result;
|
let result;
|
||||||
let searchValue = payload.searchValue;
|
let searchValue = payload.searchValue;
|
||||||
let isENSName = false;
|
const foundEnsExt = ENS_WHITELIST.find(ensExt => searchValue.endsWith(ensExt));
|
||||||
if (searchValue.endsWith('.eth')) {
|
if (foundEnsExt) {
|
||||||
isENSName = true;
|
|
||||||
yield fetchEnsRecord({name: payload.searchValue});
|
yield fetchEnsRecord({name: payload.searchValue});
|
||||||
const ensRecord = yield select(getEnsRecordForName, searchValue);
|
const ensRecord = yield select(getEnsRecordForName, searchValue);
|
||||||
|
|
||||||
|
@ -63,7 +67,7 @@ export function *searchExplorer(entity, payload) {
|
||||||
return yield put(entity.success(result));
|
return yield put(entity.success(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isENSName) {
|
if (foundEnsExt) {
|
||||||
return yield put(entity.success({error: `ENS resolved to ${searchValue}, but Embark couldn't find what this address represents`}));
|
return yield put(entity.success({error: `ENS resolved to ${searchValue}, but Embark couldn't find what this address represents`}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,5 +63,11 @@
|
||||||
"implicit": "implicit",
|
"implicit": "implicit",
|
||||||
"explicit": "explicit"
|
"explicit": "explicit"
|
||||||
},
|
},
|
||||||
"embarkResourceOrigin": "http://embark"
|
"embarkResourceOrigin": "http://embark",
|
||||||
|
"ens": {
|
||||||
|
"whitelist": [
|
||||||
|
"eth",
|
||||||
|
"xyz"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ class BlockchainConnector {
|
||||||
function checkVersion(next) {
|
function checkVersion(next) {
|
||||||
// TODO: web3_clientVersion method is currently not implemented in web3.js 1.0
|
// TODO: web3_clientVersion method is currently not implemented in web3.js 1.0
|
||||||
self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => {
|
self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => {
|
||||||
if (err) {
|
if (err || !version) {
|
||||||
self.isWeb3Ready = false;
|
self.isWeb3Ready = false;
|
||||||
return next(null, {name: "Ethereum node not found", status: 'off'});
|
return next(null, {name: "Ethereum node not found", status: 'off'});
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,37 +50,32 @@ class ContractDeployer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async.map(args, (arg, nextEachCb) => {
|
function checkArgs(argus, cb) {
|
||||||
|
async.map(argus, (arg, nextEachCb) => {
|
||||||
if (arg[0] === "$") {
|
if (arg[0] === "$") {
|
||||||
parseArg(arg, nextEachCb);
|
return parseArg(arg, nextEachCb);
|
||||||
} else if (Array.isArray(arg)) {
|
|
||||||
async.map(arg, (sub_arg, nextSubEachCb) => {
|
|
||||||
if (sub_arg[0] === "$") {
|
|
||||||
parseArg(sub_arg, nextSubEachCb);
|
|
||||||
} else if(typeof sub_arg === 'string' && sub_arg.indexOf('.eth') === sub_arg.length - 4) {
|
|
||||||
self.events.request("ens:resolve", sub_arg, (err, name) => {
|
|
||||||
if(err) {
|
|
||||||
return nextSubEachCb(err);
|
|
||||||
}
|
}
|
||||||
return nextSubEachCb(err, name);
|
|
||||||
});
|
if (Array.isArray(arg)) {
|
||||||
} else {
|
return checkArgs(arg, nextEachCb);
|
||||||
nextSubEachCb(null, sub_arg);
|
|
||||||
}
|
}
|
||||||
}, (err, subRealArgs) => {
|
|
||||||
nextEachCb(null, subRealArgs);
|
self.events.request('ens:isENSName', arg, (isENSName) => {
|
||||||
});
|
if (isENSName) {
|
||||||
} else if(typeof arg === 'string' && arg.indexOf('.eth') === arg.length - 4) {
|
return self.events.request("ens:resolve", arg, (err, address) => {
|
||||||
self.events.request("ens:resolve", arg, (err, name) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return nextEachCb(err);
|
return nextEachCb(err);
|
||||||
}
|
}
|
||||||
return nextEachCb(err, name);
|
nextEachCb(err, address);
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
nextEachCb(null, arg);
|
|
||||||
}
|
}
|
||||||
}, callback);
|
|
||||||
|
nextEachCb(null, arg);
|
||||||
|
});
|
||||||
|
}, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkArgs(args, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAndDeployContract(contract, params, callback) {
|
checkAndDeployContract(contract, params, callback) {
|
||||||
|
|
|
@ -43,8 +43,8 @@ function registerSubDomain(ens, registrar, resolver, defaultAccount, subdomain,
|
||||||
callback(null, transaction);
|
callback(null, transaction);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.error(err.message || err);
|
logger.error('Failed to register with error:', err.message || err);
|
||||||
callback('Failed to register with error: ' + (err.message || err));
|
callback(err.message || err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ const embarkJsUtils = require('embarkjs').Utils;
|
||||||
const reverseAddrSuffix = '.addr.reverse';
|
const reverseAddrSuffix = '.addr.reverse';
|
||||||
const ENSFunctions = require('./ENSFunctions');
|
const ENSFunctions = require('./ENSFunctions');
|
||||||
import { ZERO_ADDRESS } from '../../utils/addressUtils';
|
import { ZERO_ADDRESS } from '../../utils/addressUtils';
|
||||||
|
import {ens} from '../../constants';
|
||||||
|
|
||||||
|
const ENS_WHITELIST = ens.whitelist;
|
||||||
|
|
||||||
const MAINNET_ID = '1';
|
const MAINNET_ID = '1';
|
||||||
const ROPSTEN_ID = '3';
|
const ROPSTEN_ID = '3';
|
||||||
|
@ -65,6 +68,7 @@ class ENS {
|
||||||
this.configured = false;
|
this.configured = false;
|
||||||
|
|
||||||
this.events.setCommandHandler("ens:resolve", this.ensResolve.bind(this));
|
this.events.setCommandHandler("ens:resolve", this.ensResolve.bind(this));
|
||||||
|
this.events.setCommandHandler("ens:isENSName", this.isENSName.bind(this));
|
||||||
|
|
||||||
if (this.namesConfig === {} ||
|
if (this.namesConfig === {} ||
|
||||||
this.namesConfig.enabled !== true ||
|
this.namesConfig.enabled !== true ||
|
||||||
|
@ -148,8 +152,8 @@ class ENS {
|
||||||
// Code inspired by https://github.com/monkybrain/ipfs-to-ens
|
// Code inspired by https://github.com/monkybrain/ipfs-to-ens
|
||||||
const {name, storageHash} = options;
|
const {name, storageHash} = options;
|
||||||
|
|
||||||
if (!utils.isValidEthDomain(name)) {
|
if (!this.isENSName(name)) {
|
||||||
return cb('Invalid domain name ' + name);
|
return cb(__('Invalid domain name: {{name}}\nValid extensions are: {{extenstions}}', {name, extenstions: ENS_WHITELIST.join(', ')}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let hashedName = namehash.hash(name);
|
let hashedName = namehash.hash(name);
|
||||||
|
@ -157,7 +161,7 @@ class ENS {
|
||||||
try {
|
try {
|
||||||
contentHash = utils.hashTo32ByteHexString(storageHash);
|
contentHash = utils.hashTo32ByteHexString(storageHash);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return cb('Invalid IPFS hash');
|
return cb(__('Invalid IPFS hash'));
|
||||||
}
|
}
|
||||||
// Set content
|
// Set content
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
@ -339,10 +343,18 @@ class ENS {
|
||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function registrar(next) {
|
function checkRootNode(next) {
|
||||||
if (!self.registration || !self.registration.rootDomain) {
|
if (!self.registration || !self.registration.rootDomain) {
|
||||||
return next(NO_REGISTRATION);
|
return next(NO_REGISTRATION);
|
||||||
}
|
}
|
||||||
|
if (!self.isENSName(self.registration.rootDomain)) {
|
||||||
|
|
||||||
|
return next(__('Invalid domain name: {{name}}\nValid extensions are: {{extenstions}}',
|
||||||
|
{name: self.registration.rootDomain, extenstions: ENS_WHITELIST.join(', ')}));
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
function registrar(next) {
|
||||||
const registryAddress = self.ensConfig.ENSRegistry.deployedAddress;
|
const registryAddress = self.ensConfig.ENSRegistry.deployedAddress;
|
||||||
const rootNode = namehash.hash(self.registration.rootDomain);
|
const rootNode = namehash.hash(self.registration.rootDomain);
|
||||||
const contract = self.ensConfig.FIFSRegistrar;
|
const contract = self.ensConfig.FIFSRegistrar;
|
||||||
|
@ -480,6 +492,16 @@ class ENS {
|
||||||
cb(null, result);
|
cb(null, result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isENSName(name, callback = () => {}) {
|
||||||
|
if (typeof name !== 'string') {
|
||||||
|
callback(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const result = Boolean(ENS_WHITELIST.find(ensExt => name.endsWith(ensExt)));
|
||||||
|
callback(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ENS;
|
module.exports = ENS;
|
||||||
|
|
|
@ -18,9 +18,9 @@ class TransactionTracker {
|
||||||
}
|
}
|
||||||
|
|
||||||
onBlockHeader(blockHeader) {
|
onBlockHeader(blockHeader) {
|
||||||
this.events.request("blockchain:block:byNumber", blockHeader.hash, (err, block) => {
|
this.events.request("blockchain:block:byNumber", blockHeader.number , (err, block) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return this.logger.error('Error getting block header', err);
|
return this.logger.error('Error getting block header', err.message || err);
|
||||||
}
|
}
|
||||||
// Don't know why, but sometimes we receive nothing
|
// Don't know why, but sometimes we receive nothing
|
||||||
if (!block || !block.transactions) {
|
if (!block || !block.transactions) {
|
||||||
|
|
|
@ -338,13 +338,6 @@ function isValidDomain(domain) {
|
||||||
return isValidDomain(domain);
|
return isValidDomain(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidEthDomain(ethDomain) {
|
|
||||||
if (!isValidDomain(ethDomain)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ethDomain.substring(ethDomain.lastIndexOf('.'), ethDomain.length) === '.eth';
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeParams(typesArray, hexString) {
|
function decodeParams(typesArray, hexString) {
|
||||||
var Web3EthAbi = require('web3-eth-abi');
|
var Web3EthAbi = require('web3-eth-abi');
|
||||||
return Web3EthAbi.decodeParameters(typesArray, hexString);
|
return Web3EthAbi.decodeParameters(typesArray, hexString);
|
||||||
|
@ -588,7 +581,6 @@ module.exports = {
|
||||||
isHex,
|
isHex,
|
||||||
hashTo32ByteHexString,
|
hashTo32ByteHexString,
|
||||||
isValidDomain,
|
isValidDomain,
|
||||||
isValidEthDomain,
|
|
||||||
pingEndpoint,
|
pingEndpoint,
|
||||||
decodeParams,
|
decodeParams,
|
||||||
runCmd,
|
runCmd,
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
pragma solidity ^0.4.24;
|
pragma solidity ^0.4.24;
|
||||||
contract AnotherStorage {
|
contract AnotherStorage {
|
||||||
address public simpleStorageAddress;
|
address public simpleStorageAddress;
|
||||||
address simpleStorageAddress2;
|
address public ens;
|
||||||
address ens;
|
|
||||||
|
|
||||||
constructor(address addr, address _ens) public {
|
constructor(address addr, address _ens) public {
|
||||||
simpleStorageAddress = addr;
|
simpleStorageAddress = addr;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const AnotherStorage = require('Embark/contracts/AnotherStorage');
|
const AnotherStorage = require('Embark/contracts/AnotherStorage');
|
||||||
const SimpleStorage = require('Embark/contracts/SimpleStorage');
|
const SimpleStorage = require('Embark/contracts/SimpleStorage');
|
||||||
|
let accounts;
|
||||||
|
|
||||||
config({
|
config({
|
||||||
contracts: {
|
contracts: {
|
||||||
|
@ -12,13 +13,20 @@ config({
|
||||||
args: ["$SimpleStorage", "embark.eth"]
|
args: ["$SimpleStorage", "embark.eth"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, (err, accs) => {
|
||||||
|
accounts = accs;
|
||||||
});
|
});
|
||||||
|
|
||||||
contract("AnotherStorage", function() {
|
contract("AnotherStorage", function() {
|
||||||
this.timeout(0);
|
this.timeout(0);
|
||||||
|
|
||||||
it("set SimpleStorage address", async function() {
|
it("set SimpleStorage address", async function() {
|
||||||
let result = await AnotherStorage.methods.simpleStorageAddress().call();
|
const result = await AnotherStorage.methods.simpleStorageAddress().call();
|
||||||
assert.equal(result.toString(), SimpleStorage.options.address);
|
assert.equal(result.toString(), SimpleStorage.options.address);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("set ENS address", async function() {
|
||||||
|
const result = await AnotherStorage.methods.ens().call();
|
||||||
|
assert.equal(result.toString(), accounts[0]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue