UNPKG

blockstack

Version:

The Blockstack Javascript library for identity and authentication.

347 lines (269 loc) 13.9 kB
'use strict'; 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); }); }); }