blockstack
Version:
The Blockstack Javascript library for identity and authentication.
347 lines (269 loc) • 13.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.runStorageTests = runStorageTests;
var _tape = require('tape');
var _tape2 = _interopRequireDefault(_tape);
var _fetchMock = require('fetch-mock');
var _fetchMock2 = _interopRequireDefault(_fetchMock);
var _proxyquire5 = require('proxyquire');
var _proxyquire6 = _interopRequireDefault(_proxyquire5);
var _sinon = require('sinon');
var _sinon2 = _interopRequireDefault(_sinon);
var _bitcoinjsLib = require('bitcoinjs-lib');
var _bitcoinjsLib2 = _interopRequireDefault(_bitcoinjsLib);
var _mockLocalStorage = require('mock-local-storage');
var _mockLocalStorage2 = _interopRequireDefault(_mockLocalStorage);
var _hub = require('../../../lib/storage/hub');
var _storage = require('../../../lib/storage');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
global.window = {};
window.localStorage = global.localStorage;
function runStorageTests() {
(0, _tape2.default)('getFile unencrypted', function (t) {
t.plan(2);
var path = 'file.json';
var gaiaHubConfig = {
address: '1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U',
server: 'https://hub.blockstack.org',
token: '',
url_prefix: 'gaia.testblockstack.org/hub/'
};
var fullReadUrl = 'https://gaia.testblockstack.org/hub/1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U/file.json';
var fileContent = { test: 'test' };
var getOrSetLocalGaiaHubConnection = _sinon2.default.stub().resolves(gaiaHubConfig);
var getFullReadUrl = _sinon2.default.stub().resolves(fullReadUrl);
var _proxyquire = (0, _proxyquire6.default)('../../../lib/storage', {
'./hub': { getOrSetLocalGaiaHubConnection: getOrSetLocalGaiaHubConnection, getFullReadUrl: getFullReadUrl }
}),
getFile = _proxyquire.getFile;
_fetchMock2.default.get(fullReadUrl, fileContent);
getFile(path).then(function (file) {
t.ok(file, 'Returns file content');
t.same(JSON.parse(file), fileContent);
});
});
(0, _tape2.default)('getFile unencrypted - multi-reader', function (t) {
t.plan(4);
var path = 'file.json';
var gaiaHubConfig = {
address: '1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U',
server: 'https://hub.blockstack.org',
token: '',
url_prefix: 'gaia.testblockstack.org/hub/'
};
var fullReadUrl = 'https://gaia.testblockstack.org/hub/1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U/file.json';
var fileContent = { test: 'test' };
var getOrSetLocalGaiaHubConnection = _sinon2.default.stub().resolves(gaiaHubConfig);
var getFullReadUrl = _sinon2.default.stub().resolves(fullReadUrl);
var _proxyquire2 = (0, _proxyquire6.default)('../../../lib/storage', {
'./hub': { getOrSetLocalGaiaHubConnection: getOrSetLocalGaiaHubConnection, getFullReadUrl: getFullReadUrl }
}),
getFile = _proxyquire2.getFile;
_fetchMock2.default.get(fullReadUrl, fileContent);
var nameLookupUrl = 'http://localhost:6270/v1/names/yukan.id';
var nameRecord = { "status": "registered", "zonefile": "$ORIGIN yukan.id\n$TTL 3600\n_http._tcp URI 10 1 \"https://gaia.blockstack.org/hub/16zVUoP7f15nfTiHw2UNiX8NT5SWYqwNv3/0/profile.json\"\n", "expire_block": 581432, "blockchain": "bitcoin", "last_txid": "f7fa811518566b1914a098c3bd61a810aee56390815bd608490b0860ac1b5b4d", "address": "16zVUoP7f15nfTiHw2UNiX8NT5SWYqwNv3", "zonefile_hash": "98f42e11026d42d394b3424d4d7f0cccd6f376e2" };
var nameRecordContent = JSON.stringify(nameRecord);
_fetchMock2.default.get(nameLookupUrl, nameRecordContent);
var profileUrl = 'https://gaia.blockstack.org/hub/16zVUoP7f15nfTiHw2UNiX8NT5SWYqwNv3/0/profile.json';
var profileContent = [{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJqdGkiOiJjNDhmOTQ0OC1hMGZlLTRiOWUtOWQ2YS1mYzA5MzhjOGUyNzAiLCJpYXQiOiIyMDE4LTAxLTA4VDE4OjIyOjI0Ljc5NloiLCJleHAiOiIyMDE5LTAxLTA4VDE4OjIyOjI0Ljc5NloiLCJzdWJqZWN0Ijp7InB1YmxpY0tleSI6IjAyNDg3YTkxY2Q5NjZmYWVjZWUyYWVmM2ZkZTM3MjgwOWI0NmEzNmVlMTkyNDhjMDFmNzJiNjQ1ZjQ0Y2VmMmUyYyJ9LCJpc3N1ZXIiOnsicHVibGljS2V5IjoiMDI0ODdhOTFjZDk2NmZhZWNlZTJhZWYzZmRlMzcyODA5YjQ2YTM2ZWUxOTI0OGMwMWY3MmI2NDVmNDRjZWYyZTJjIn0sImNsYWltIjp7IkB0eXBlIjoiUGVyc29uIiwiQGNvbnRleHQiOiJodHRwOi8vc2NoZW1hLm9yZyIsImltYWdlIjpbeyJAdHlwZSI6IkltYWdlT2JqZWN0IiwibmFtZSI6ImF2YXRhciIsImNvbnRlbnRVcmwiOiJodHRwczovL3d3dy5kcm9wYm94LmNvbS9zL2oxaDBrdHMwbTdhYWRpcC9hdmF0YXItMD9kbD0xIn1dLCJnaXZlbk5hbWUiOiIiLCJmYW1pbHlOYW1lIjoiIiwiZGVzY3JpcHRpb24iOiIiLCJhY2NvdW50IjpbeyJAdHlwZSI6IkFjY291bnQiLCJwbGFjZWhvbGRlciI6ZmFsc2UsInNlcnZpY2UiOiJoYWNrZXJOZXdzIiwiaWRlbnRpZmllciI6Inl1a2FubCIsInByb29mVHlwZSI6Imh0dHAiLCJwcm9vZlVybCI6Imh0dHBzOi8vbmV3cy55Y29tYmluYXRvci5jb20vdXNlcj9pZD15dWthbmwifSx7IkB0eXBlIjoiQWNjb3VudCIsInBsYWNlaG9sZGVyIjpmYWxzZSwic2VydmljZSI6ImdpdGh1YiIsImlkZW50aWZpZXIiOiJ5a25sIiwicHJvb2ZUeXBlIjoiaHR0cCIsInByb29mVXJsIjoiaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20veWtubC8xZjcwMThiOThmNzE2ZjAxNWE2Y2Y0NGZkYTA4MDZkNyJ9LHsiQHR5cGUiOiJBY2NvdW50IiwicGxhY2Vob2xkZXIiOmZhbHNlLCJzZXJ2aWNlIjoidHdpdHRlciIsImlkZW50aWZpZXIiOiJ5dWthbmwiLCJwcm9vZlR5cGUiOiJodHRwIiwicHJvb2ZVcmwiOiJodHRwczovL3R3aXR0ZXIuY29tL3l1a2FuTC9zdGF0dXMvOTE2NzQwNzQ5MjM2MTAxMTIwIn1dLCJuYW1lIjoiS2VuIExpYW8iLCJhcHBzIjp7Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MCI6Imh0dHBzOi8vZ2FpYS5ibG9ja3N0YWNrLm9yZy9odWIvMUREVXFmS3RRZ1lOdDcyMnd1QjRaMmZQQzdhaU5HUWE1Ui8ifX19.UyQNZ02kBFHEovbwiGaS-VQd57w9kcwn1Nt3QbW3afEMArg1OndmeplB7lzjMuRCLAi-88lkpQLkFw7LwKZ31Q",
"decodedToken": {
"header": {
"typ": "JWT",
"alg": "ES256K"
},
"payload": {
"jti": "c48f9448-a0fe-4b9e-9d6a-fc0938c8e270",
"iat": "2018-01-08T18:22:24.796Z",
"exp": "2019-01-08T18:22:24.796Z",
"subject": {
"publicKey": "02487a91cd966faecee2aef3fde372809b46a36ee19248c01f72b645f44cef2e2c"
},
"issuer": {
"publicKey": "02487a91cd966faecee2aef3fde372809b46a36ee19248c01f72b645f44cef2e2c"
},
"claim": {
"@type": "Person",
"@context": "http://schema.org",
"image": [{
"@type": "ImageObject",
"name": "avatar",
"contentUrl": "https://www.dropbox.com/s/j1h0kts0m7aadip/avatar-0?dl=1"
}],
"givenName": "",
"familyName": "",
"description": "",
"account": [{
"@type": "Account",
"placeholder": false,
"service": "hackerNews",
"identifier": "yukanl",
"proofType": "http",
"proofUrl": "https://news.ycombinator.com/user?id=yukanl"
}, {
"@type": "Account",
"placeholder": false,
"service": "github",
"identifier": "yknl",
"proofType": "http",
"proofUrl": "https://gist.github.com/yknl/1f7018b98f716f015a6cf44fda0806d7"
}, {
"@type": "Account",
"placeholder": false,
"service": "twitter",
"identifier": "yukanl",
"proofType": "http",
"proofUrl": "https://twitter.com/yukanL/status/916740749236101120"
}],
"name": "Ken Liao",
"apps": {
"http://localhost:8080": "https://gaia.blockstack.org/hub/1DDUqfKtQgYNt722wuB4Z2fPC7aiNGQa5R/"
}
}
},
"signature": "UyQNZ02kBFHEovbwiGaS-VQd57w9kcwn1Nt3QbW3afEMArg1OndmeplB7lzjMuRCLAi-88lkpQLkFw7LwKZ31Q"
}
}];
_fetchMock2.default.get(profileUrl, profileContent);
var fileUrl = 'https://gaia.blockstack.org/hub/1DDUqfKtQgYNt722wuB4Z2fPC7aiNGQa5R/file.json';
var fileContents = JSON.stringify({ "key": "value" });
_fetchMock2.default.get(fileUrl, fileContents);
var options = {
username: 'yukan.id',
app: 'http://localhost:8080'
};
getFile(path, options).then(function (file) {
t.ok(file, 'Returns file content');
t.same(JSON.parse(file), JSON.parse(fileContents));
});
var optionsNoApp = {
username: 'yukan.id'
};
global.window = {
location: {
origin: 'http://localhost:8080'
}
};
getFile(path, optionsNoApp).then(function (file) {
t.ok(file, 'Returns file content');
t.same(JSON.parse(file), JSON.parse(fileContents));
});
});
(0, _tape2.default)('putFile unencrypted', function (t) {
t.plan(1);
var path = 'file.json';
var gaiaHubConfig = {
address: '1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U',
server: 'https://hub.blockstack.org',
token: '',
url_prefix: 'gaia.testblockstack.org/hub/'
};
var fullReadUrl = 'https://gaia.testblockstack.org/hub/1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U/file.json';
var fileContent = { test: 'test' };
var getOrSetLocalGaiaHubConnection = _sinon2.default.stub().resolves(gaiaHubConfig);
var uploadToGaiaHub = _sinon2.default.stub().resolves(fullReadUrl);
var _proxyquire3 = (0, _proxyquire6.default)('../../../lib/storage', {
'./hub': { getOrSetLocalGaiaHubConnection: getOrSetLocalGaiaHubConnection, uploadToGaiaHub: uploadToGaiaHub }
}),
putFile = _proxyquire3.putFile;
putFile(path, fileContent).then(function (publicURL) {
t.ok(publicURL, fullReadUrl);
});
});
(0, _tape2.default)('fetch404null', function (t) {
t.plan(2);
var config = { address: '19MoWG8u88L6t766j7Vne21Mg4wHsCQ7vk',
url_prefix: 'gaia.testblockstack.org/hub/',
token: '',
server: 'hub.testblockstack.org' };
global.localStorage.setItem(_hub.BLOCKSTACK_GAIA_HUB_LABEL, JSON.stringify(config));
_fetchMock2.default.get('' + config.url_prefix + config.address + '/foo.json', { status: 404 });
(0, _storage.getFile)('foo.json', false).then(function (x) {
return t.equal(x, null, '404 should return null');
});
(0, _storage.getFile)('foo.json', true).then(function (x) {
return t.equal(x, null, '404 should return null, even if we try to decrypt');
});
});
(0, _tape2.default)('uploadToGaiaHub', function (t) {
t.plan(2);
var config = { address: '19MoWG8u88L6t766j7Vne21Mg4wHsCQ7vk',
url_prefix: 'gaia.testblockstack.org',
token: '',
server: 'hub.testblockstack.org' };
_fetchMock2.default.post(config.server + '/store/' + config.address + '/foo.json', JSON.stringify({ publicURL: '${config.url_prefix}/${config.address}/foo.json' }));
(0, _hub.uploadToGaiaHub)('foo.json', 'foo the bar', config).then(function (url) {
t.ok(url, 'URL returned');
t.equal(url, '${config.url_prefix}/${config.address}/foo.json');
});
});
(0, _tape2.default)('getFullReadUrl', function (t) {
t.plan(1);
var config = { address: '19MoWG8u88L6t766j7Vne21Mg4wHsCQ7vk',
url_prefix: 'gaia.testblockstack.org',
token: '',
server: 'hub.testblockstack.org' };
var outUrl = (0, _hub.getFullReadUrl)('foo.json', config);
t.equal('' + config.url_prefix + config.address + '/foo.json', outUrl);
});
(0, _tape2.default)('connectToGaiaHub', function (t) {
t.plan(5);
var hubServer = 'hub.testblockstack.org';
var hubInfo = {
read_url_prefix: 'gaia.testblockstack.org',
challenge_text: 'please-sign'
};
var privateKey = 'a5c61c6ca7b3e7e55edee68566aeab22e4da26baa285c7bd10e8d2218aa3b229';
var address = '1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U';
var publicKey = '027d28f9951ce46538951e3697c62588a87f1f1f295de4a14fdd4c780fc52cfe69';
_fetchMock2.default.get(hubServer + '/hub_info', JSON.stringify(hubInfo));
(0, _hub.connectToGaiaHub)(hubServer, privateKey).then(function (config) {
t.ok(config, 'Config returned by connectToGaiaHub()');
t.equal(hubInfo.read_url_prefix, config.url_prefix);
t.equal(address, config.address);
t.equal(hubServer, config.server);
var verificationKey = _bitcoinjsLib2.default.ECPair.fromPublicKeyBuffer(Buffer.from(publicKey, 'hex'));
var decoded = JSON.parse(Buffer.from(config.token, 'base64').toString());
var signature = _bitcoinjsLib2.default.ECSignature.fromDER(Buffer.from(decoded.signature, 'hex'));
t.ok(verificationKey.verify(_bitcoinjsLib2.default.crypto.sha256(hubInfo.challenge_text), signature), 'Verified token');
});
});
(0, _tape2.default)('getBucketUrl', function (t) {
t.plan(2);
var hubServer = 'hub2.testblockstack.org';
var hubInfo = {
read_url_prefix: 'https://gaia.testblockstack.org/hub/',
challenge_text: 'please-sign'
};
var privateKey = 'a5c61c6ca7b3e7e55edee68566aeab22e4da26baa285c7bd10e8d2218aa3b229';
var address = '1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U';
_fetchMock2.default.get(hubServer + '/hub_info', JSON.stringify(hubInfo));
(0, _hub.getBucketUrl)(hubServer, privateKey).then(function (bucketUrl) {
t.ok(bucketUrl, 'App index file URL returned by getBucketUrl');
t.equal(bucketUrl, '' + hubInfo.read_url_prefix + address + '/');
});
});
(0, _tape2.default)('getUserAppFileUrl', function (t) {
t.plan(2);
var path = 'file.json';
var name = 'test.id';
var appOrigin = 'testblockstack.org';
var profile = {
'apps': {
'testblockstack.org': 'https://gaia.testblockstack.org/hub/1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U/'
}
};
var fileUrl = "https://gaia.testblockstack.org/hub/1NZNxhoxobqwsNvTb16pdeiqvFvce3Yg8U/file.json";
var lookupProfile = _sinon2.default.stub().resolves(profile);
var _proxyquire4 = (0, _proxyquire6.default)('../../../lib/storage', {
'../profiles': { lookupProfile: lookupProfile }
}),
getUserAppFileUrl = _proxyquire4.getUserAppFileUrl;
getUserAppFileUrl(path, name, appOrigin).then(function (url) {
t.ok(url, 'Returns user app file url');
t.equals(url, fileUrl);
});
});
}