UNPKG

3box

Version:
1,495 lines (1,218 loc) 59.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } var localstorage = require('store'); var IPFS = require('ipfs'); var _require = require('3id-blockchain-utils'), createLink = _require.createLink, validateLink = _require.validateLink; var ThreeId = require('./3id'); var Replicator = require('./replicator'); var PublicStore = require('./publicStore'); var PrivateStore = require('./privateStore'); var Verified = require('./verified'); var Space = require('./space'); var utils = require('./utils/index'); var idUtils = require('./utils/id'); var config = require('./config.js'); var BoxApi = require('./api'); var IPFSRepo = require('ipfs-repo'); var LevelStore = require('datastore-level'); var didJWT = require('did-jwt'); var ThreeIdConnect = require('3id-connect').ThreeIdConnect; var PINNING_NODE = config.pinning_node; var ADDRESS_SERVER_URL = config.address_server_url; var IPFS_OPTIONS = config.ipfs_options; var IFRAME_STORE_URL = 'https://connect.3box.io'; var globalIPFS, globalIPFSPromise, threeIdConnect; var browserHuh = typeof window !== 'undefined' && typeof document !== 'undefined'; if (browserHuh) threeIdConnect = new ThreeIdConnect(IFRAME_STORE_URL); /** * @extends BoxApi */ var Box = /*#__PURE__*/function (_BoxApi) { (0, _inherits2["default"])(Box, _BoxApi); var _super = _createSuper(Box); /** * Please use the **openBox** method to instantiate a 3Box * @constructor */ function Box(provider, ipfs) { var _this; var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; (0, _classCallCheck2["default"])(this, Box); _this = _super.call(this); _this._provider = provider; _this._ipfs = ipfs; _this._serverUrl = opts.addressServer || ADDRESS_SERVER_URL; /** * @property {KeyValueStore} public access the profile store of the users 3Box */ _this["public"] = null; /** * @property {KeyValueStore} private access the private store of the users 3Box */ _this["private"] = null; /** * @property {Verified} verified check and create verifications */ _this.verified = new Verified((0, _assertThisInitialized2["default"])(_this)); /** * @property {Object} spaces an object containing all open spaces indexed by their name. */ _this.spaces = {}; /** * @property {Promise} syncDone A promise that is resolved when the box is synced */ _this.syncDone = null; _this.hasPublishedLink = {}; return _this; } (0, _createClass2["default"])(Box, [{ key: "_init", value: function () { var _init2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(opts) { return _regenerator["default"].wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return Replicator.create(this._ipfs, opts); case 2: this.replicator = _context.sent; case 3: case "end": return _context.stop(); } } }, _callee, this); })); function _init(_x) { return _init2.apply(this, arguments); } return _init; }() }, { key: "_load", value: function () { var _load2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { var _this2 = this; var opts, address, _ref, rootStoreAddress, did, authData, rootstoreName, key, _args2 = arguments; return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: opts = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}; _context2.t0 = opts.address; if (_context2.t0) { _context2.next = 6; break; } _context2.next = 5; return this._3id.getAddress(); case 5: _context2.t0 = _context2.sent; case 6: address = _context2.t0; if (!address) { _context2.next = 13; break; } _context2.next = 10; return this._getLinkedData(address); case 10: _context2.t1 = _context2.sent; _context2.next = 14; break; case 13: _context2.t1 = {}; case 14: _ref = _context2.t1; rootStoreAddress = _ref.rootStoreAddress; did = _ref.did; if (!rootStoreAddress) { _context2.next = 29; break; } _context2.next = 20; return this.replicator.start(rootStoreAddress, did, { profile: true }); case 20: _context2.next = 22; return this.replicator.rootstoreSyncDone; case 22: _context2.next = 24; return this.replicator.getAuthData(); case 24: authData = _context2.sent; _context2.next = 27; return this._3id.authenticate(opts.spaces, { authData: authData, address: address }); case 27: _context2.next = 38; break; case 29: _context2.next = 31; return this._3id.authenticate(opts.spaces, { address: address }); case 31: rootstoreName = this._3id.muportFingerprint + '.root'; _context2.next = 34; return this._3id.getPublicKeys(null, true); case 34: key = _context2.sent.signingKey; _context2.next = 37; return this.replicator["new"](rootstoreName, key, this._3id.DID); case 37: this._publishRootStore(this.replicator.rootstore.address.toString()); case 38: _context2.t2 = this.replicator.rootstore; _context2.next = 41; return this._3id.getOdbId(); case 41: _context2.t3 = _context2.sent; _context2.t2.setIdentity.call(_context2.t2, _context2.t3); this.syncDone = this.replicator.syncDone; this._3id.events.on('new-auth-method', function (authData) { _this2._writeRootstoreEntry(Replicator.entryTypes.AUTH_DATA, authData); }); this._3id.events.on('new-link-proof', function (proof) { _this2._writeAddressLink(proof); }); this._3id.startUpdatePolling(); this["public"] = new PublicStore(this._3id.muportFingerprint + '.public', this._linkProfile.bind(this), this.replicator, this._3id); this["private"] = new PrivateStore(this._3id.muportFingerprint + '.private', this.replicator, this._3id); _context2.next = 51; return this["public"]._load(); case 51: _context2.next = 53; return this["private"]._load(); case 53: case "end": return _context2.stop(); } } }, _callee2, this); })); function _load() { return _load2.apply(this, arguments); } return _load; }() /** * Creates an instance of 3Box * * @param {provider} provider A 3ID provider, or ethereum provider * @param {Object} opts Optional parameters * @param {String} opts.pinningNode A string with an ipfs multi-address to a 3box pinning node * @param {Object} opts.ipfs A js-ipfs ipfs object * @param {String} opts.addressServer URL of the Address Server * @return {Box} the 3Box session instance */ }, { key: "auth", /** * Authenticate the user * * @param {Array<String>} spaces A list of spaces to authenticate (optional) * @param {Object} opts Optional parameters * @param {String} opts.address An ethereum address * @param {Function} opts.consentCallback A function that will be called when the user has consented to opening the box */ value: function () { var _auth = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4() { var _this3 = this; var spaces, opts, _args4 = arguments; return _regenerator["default"].wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: spaces = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : []; opts = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {}; opts.address = opts.address ? opts.address.toLowerCase() : opts.address; this._3idEthAddress = opts.address; // Enabled once becomes default // if (!this._provider.is3idProvider && threeIdConnect) { // this._provider = await threeIdConnect.get3idProvider() // } if (this._3id) { _context4.next = 14; break; } if (!(!this._provider.is3idProvider && !opts.address)) { _context4.next = 7; break; } throw new Error('auth: address needed when 3ID provider is not used'); case 7: _context4.next = 9; return ThreeId.getIdFromEthAddress(opts.address, this._provider, this._ipfs, this.replicator._orbitdb.keystore, opts); case 9: this._3id = _context4.sent; _context4.next = 12; return this._load(Object.assign(opts, { spaces: spaces })); case 12: _context4.next = 18; break; case 14: if (!(this._provider.threeIdConnect && this._provider.migration && !opts.address)) { _context4.next = 16; break; } throw new Error('auth: address needed when 3ID provider not given'); case 16: _context4.next = 18; return this._3id.authenticate(spaces, { address: opts.address }); case 18: _context4.next = 20; return Promise.all(spaces.map( /*#__PURE__*/function () { var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(space) { return _regenerator["default"].wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: if (!_this3.spaces[space]) { _context3.next = 3; break; } _context3.next = 3; return _this3.spaces[space]._authThreads(_this3._3id); case 3: case "end": return _context3.stop(); } } }, _callee3); })); return function (_x2) { return _ref2.apply(this, arguments); }; }())); case 20: case "end": return _context4.stop(); } } }, _callee4, this); })); function auth() { return _auth.apply(this, arguments); } return auth; }() /** * Opens the 3Box associated with the given address * * @param {String} address An ethereum address * @param {provider} provider An ethereum or 3ID provider * @param {Object} opts Optional parameters * @param {Function} opts.consentCallback A function that will be called when the user has consented to opening the box * @param {String} opts.pinningNode A string with an ipfs multi-address to a 3box pinning node * @param {Object} opts.ipfs A js-ipfs ipfs object * @param {String} opts.addressServer URL of the Address Server * @param {String} opts.contentSignature A signature, provided by a client of 3box using the private keys associated with the given address, of the 3box consent message * @return {Box} the 3Box instance for the given address */ }, { key: "openSpace", /** * Opens the space with the given name in the users 3Box * * @param {String} name The name of the space * @param {Object} opts Optional parameters * @param {Function} opts.consentCallback A function that will be called when the user has consented to opening the box * @param {Function} opts.onSyncDone A function that will be called when the space has finished syncing with the pinning node * @return {Space} the Space instance for the given space name */ value: function () { var _openSpace = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(name) { var opts, _args5 = arguments; return _regenerator["default"].wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: opts = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {}; opts = Object.assign(opts, { address: this._3idEthAddress }); if (!name.includes('.')) { _context5.next = 4; break; } throw new Error('Invalid name: character "." not allowed'); case 4: if (this._3id) { _context5.next = 6; break; } throw new Error('openSpace: auth required'); case 6: if (!this.spaces[name]) { this.spaces[name] = new Space(name, this.replicator); } if (this.spaces[name].isOpen) { _context5.next = 27; break; } _context5.prev = 8; _context5.next = 11; return this.spaces[name].open(this._3id, opts); case 11: _context5.next = 13; return this.isAddressLinked(); case 13: if (_context5.sent) { _context5.next = 15; break; } this.linkAddress(); case 15: _context5.next = 25; break; case 17: _context5.prev = 17; _context5.t0 = _context5["catch"](8); delete this.spaces[name]; if (!_context5.t0.message.includes('User denied message signature.')) { _context5.next = 24; break; } throw new Error('User denied space consent.'); case 24: throw new Error('An error occured while opening space: ', _context5.t0.message); case 25: _context5.next = 28; break; case 27: if (opts.onSyncDone) { // since the space is already open we can call onSyncDone directly opts.onSyncDone(); } case 28: return _context5.abrupt("return", this.spaces[name]); case 29: case "end": return _context5.stop(); } } }, _callee5, this, [[8, 17]]); })); function openSpace(_x3) { return _openSpace.apply(this, arguments); } return openSpace; }() /** * Open a thread. Use this to start receiving updates * * @param {String} space The name of the space for this thread * @param {String} name The name of the thread * @param {Object} opts Optional parameters * @param {String} opts.firstModerator DID of first moderator of a thread, by default, user is first moderator * @param {Boolean} opts.members join a members only thread, which only members can post in, defaults to open thread * @param {Boolean} opts.noAutoSub Disable auto subscription to the thread when posting to it (default false) * @param {Boolean} opts.ghost Enable ephemeral messaging via Ghost Thread * @param {Number} opts.ghostBacklogLimit The number of posts to maintain in the ghost backlog * @param {Array<Function>} opts.ghostFilters Array of functions for filtering messages * * @return {Thread} An instance of the thread class for the joined thread */ }, { key: "openThread", value: function () { var _openThread = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6(space, name, opts) { return _regenerator["default"].wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: if (!this.spaces[space]) { this.spaces[space] = new Space(space, this.replicator); } return _context6.abrupt("return", this.spaces[space].joinThread(name, opts)); case 2: case "end": return _context6.stop(); } } }, _callee6, this); })); function openThread(_x4, _x5, _x6) { return _openThread.apply(this, arguments); } return openThread; }() /** * Sets the callback function that will be called once when the box is fully synced. * * @param {Function} syncDone The function that will be called * @return {Promise} A promise that is fulfilled when the box is syned */ }, { key: "onSyncDone", value: function () { var _onSyncDone = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(syncDone) { return _regenerator["default"].wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: _context7.next = 2; return this.syncDone; case 2: syncDone(); case 3: case "end": return _context7.stop(); } } }, _callee7, this); })); function onSyncDone(_x7) { return _onSyncDone.apply(this, arguments); } return onSyncDone; }() }, { key: "_publishRootStore", value: function () { var _publishRootStore2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9(rootStoreAddress) { var _this4 = this; var addressToken, publish; return _regenerator["default"].wrap(function _callee9$(_context9) { while (1) { switch (_context9.prev = _context9.next) { case 0: _context9.next = 2; return this._3id.signJWT({ rootStoreAddress: rootStoreAddress }); case 2: addressToken = _context9.sent; // Store odbAddress on 3box-address-server publish = /*#__PURE__*/function () { var _ref3 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(token) { return _regenerator["default"].wrap(function _callee8$(_context8) { while (1) { switch (_context8.prev = _context8.next) { case 0: _context8.prev = 0; _context8.next = 3; return utils.fetchJson(_this4._serverUrl + '/odbAddress', { address_token: token }); case 3: _context8.next = 14; break; case 5: _context8.prev = 5; _context8.t0 = _context8["catch"](0); if (!(_context8.t0.message === 'Invalid JWT')) { _context8.next = 12; break; } _context8.next = 10; return new Promise(function (resolve) { return setTimeout(resolve, 300); }); case 10: _context8.next = 12; return publish(token); case 12: if (_context8.t0.statusCode) { _context8.next = 14; break; } throw new Error(_context8.t0); case 14: case "end": return _context8.stop(); } } }, _callee8, null, [[0, 5]]); })); return function publish(_x9) { return _ref3.apply(this, arguments); }; }(); _context9.next = 6; return publish(addressToken); case 6: return _context9.abrupt("return", true); case 7: case "end": return _context9.stop(); } } }, _callee9, this); })); function _publishRootStore(_x8) { return _publishRootStore2.apply(this, arguments); } return _publishRootStore; }() }, { key: "_getLinkedData", value: function () { var _getLinkedData2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee10(ethereumAddress) { var _yield$utils$fetchJso, rootStoreAddress, did; return _regenerator["default"].wrap(function _callee10$(_context10) { while (1) { switch (_context10.prev = _context10.next) { case 0: _context10.prev = 0; _context10.next = 3; return utils.fetchJson("".concat(this._serverUrl, "/odbAddress/").concat(ethereumAddress)); case 3: _yield$utils$fetchJso = _context10.sent.data; rootStoreAddress = _yield$utils$fetchJso.rootStoreAddress; did = _yield$utils$fetchJso.did; return _context10.abrupt("return", { rootStoreAddress: rootStoreAddress, did: did }); case 9: _context10.prev = 9; _context10.t0 = _context10["catch"](0); if (!(_context10.t0.statusCode === 404)) { _context10.next = 13; break; } return _context10.abrupt("return", {}); case 13: throw new Error('Error while getting rootstore', _context10.t0); case 14: case "end": return _context10.stop(); } } }, _callee10, this, [[0, 9]]); })); function _getLinkedData(_x10) { return _getLinkedData2.apply(this, arguments); } return _getLinkedData; }() /** * @property {String} DID the DID of the user */ }, { key: "linkAddress", /** * Creates a proof that links an ethereum address to the 3Box account of the user. If given proof, it will simply be added to the root store. * * @param {Object} [link] Optional link object with type or proof * @param {Object} [link.proof] Proof object, should follow [spec](https://github.com/3box/3box/blob/master/3IPs/3ip-5.md) */ value: function () { var _linkAddress = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee11() { var link, _args11 = arguments; return _regenerator["default"].wrap(function _callee11$(_context11) { while (1) { switch (_context11.prev = _context11.next) { case 0: link = _args11.length > 0 && _args11[0] !== undefined ? _args11[0] : {}; if (this._3id) { _context11.next = 3; break; } throw new Error('linkAddress: auth required'); case 3: if (!link.proof) { _context11.next = 8; break; } _context11.next = 6; return this._writeAddressLink(link.proof); case 6: _context11.next = 10; break; case 8: _context11.next = 10; return this._linkProfile(); case 10: case "end": return _context11.stop(); } } }, _callee11, this); })); function linkAddress() { return _linkAddress.apply(this, arguments); } return linkAddress; }() /** * Remove given address link, returns true if successful * * @param {String} address address that is linked */ }, { key: "removeAddressLink", value: function () { var _removeAddressLink = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee12(address) { var linkExist, payload, oneHour, deleteToken; return _regenerator["default"].wrap(function _callee12$(_context12) { while (1) { switch (_context12.prev = _context12.next) { case 0: if (this._3id) { _context12.next = 2; break; } throw new Error('removeAddressLink: auth required'); case 2: address = address.toLowerCase(); _context12.next = 5; return this.isAddressLinked({ address: address }); case 5: linkExist = _context12.sent; if (linkExist) { _context12.next = 8; break; } throw new Error('removeAddressLink: link for given address does not exist'); case 8: payload = { address: address, type: 'delete-address-link' }; oneHour = 60 * 60; _context12.next = 12; return this._3id.signJWT(payload, { expiresIn: oneHour }); case 12: deleteToken = _context12.sent; _context12.prev = 13; _context12.next = 16; return utils.fetchJson(this._serverUrl + '/linkdelete', { delete_token: deleteToken }); case 16: _context12.next = 22; break; case 18: _context12.prev = 18; _context12.t0 = _context12["catch"](13); if (_context12.t0.statusCode) { _context12.next = 22; break; } throw new Error(_context12.t0); case 22: _context12.next = 24; return this._deleteAddressLink(address); case 24: return _context12.abrupt("return", true); case 25: case "end": return _context12.stop(); } } }, _callee12, this, [[13, 18]]); })); function removeAddressLink(_x11) { return _removeAddressLink.apply(this, arguments); } return removeAddressLink; }() /** * Checks if there is a proof that links an external account to the 3Box account of the user. If not params given and any link exists, returns true * * @param {Object} [query] Optional object with address and/or type. * @param {String} [query.type] Does the given type of link exist * @param {String} [query.address] Is the given adressed linked */ }, { key: "isAddressLinked", value: function () { var _isAddressLinked = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee13() { var query, links, linksQuery, _args13 = arguments; return _regenerator["default"].wrap(function _callee13$(_context13) { while (1) { switch (_context13.prev = _context13.next) { case 0: query = _args13.length > 0 && _args13[0] !== undefined ? _args13[0] : {}; if (this._3id) { _context13.next = 3; break; } throw new Error('isAddressLinked: auth required'); case 3: if (query.address) query.address = query.address.toLowerCase(); _context13.next = 6; return this._readAddressLinks(); case 6: links = _context13.sent; linksQuery = links.find(function (link) { var res = query.address ? link.address.toLowerCase() === query.address : true; return query.type ? res && link.type === query.type : res; }); return _context13.abrupt("return", Boolean(linksQuery)); case 9: case "end": return _context13.stop(); } } }, _callee13, this); })); function isAddressLinked() { return _isAddressLinked.apply(this, arguments); } return isAddressLinked; }() /** * Lists address links associated with this 3Box * * @return {Array} An array of link objects */ }, { key: "listAddressLinks", value: function () { var _listAddressLinks = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee14() { var entries; return _regenerator["default"].wrap(function _callee14$(_context14) { while (1) { switch (_context14.prev = _context14.next) { case 0: if (this._3id) { _context14.next = 2; break; } throw new Error('listAddressLinks: auth required'); case 2: _context14.next = 4; return this._readAddressLinks(); case 4: entries = _context14.sent; return _context14.abrupt("return", entries.reduce(function (list, entry) { var item = Object.assign({}, entry); item.linkId = item.entry.hash; delete item.entry; list.push(item); return list; }, [])); case 6: case "end": return _context14.stop(); } } }, _callee14, this); })); function listAddressLinks() { return _listAddressLinks.apply(this, arguments); } return listAddressLinks; }() }, { key: "_writeAddressLink", value: function () { var _writeAddressLink2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee15(proof) { var validProof; return _regenerator["default"].wrap(function _callee15$(_context15) { while (1) { switch (_context15.prev = _context15.next) { case 0: _context15.next = 2; return validateLink(proof); case 2: validProof = _context15.sent; if (validProof) { _context15.next = 5; break; } throw new Error('tried to write invalid link proof', proof); case 5: _context15.next = 7; return this.isAddressLinked({ address: validProof.address }); case 7: if (!_context15.sent) { _context15.next = 9; break; } return _context15.abrupt("return", true); case 9: _context15.next = 11; return this._writeRootstoreEntry(Replicator.entryTypes.ADDRESS_LINK, proof); case 11: _context15.next = 13; return utils.fetchJson(this._serverUrl + '/link', proof); case 13: case "end": return _context15.stop(); } } }, _callee15, this); })); function _writeAddressLink(_x12) { return _writeAddressLink2.apply(this, arguments); } return _writeAddressLink; }() }, { key: "_linkProfile", value: function () { var _linkProfile2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee16() { var address, proof, proofdid, issuer, jwt; return _regenerator["default"].wrap(function _callee16$(_context16) { while (1) { switch (_context16.prev = _context16.next) { case 0: _context16.next = 2; return this._3id.getAddress(); case 2: address = _context16.sent; _context16.next = 5; return this._readAddressLink(address); case 5: proof = _context16.sent; if (proof) { _context16.next = 34; break; } _context16.prev = 7; if (this._provider.is3idProvider) { _context16.next = 14; break; } _context16.next = 11; return createLink(this._3id.DID, address, this._provider); case 11: proof = _context16.sent; _context16.next = 18; break; case 14: if (!(this._provider.threeIdConnect && this._provider.migration)) { _context16.next = 18; break; } _context16.next = 17; return this._3id.linkManagementAddress(); case 17: proof = _context16.sent; case 18: _context16.next = 23; break; case 20: _context16.prev = 20; _context16.t0 = _context16["catch"](7); throw new Error('Link consent message must be signed before adding data, to link address to store', _context16.t0); case 23: _context16.prev = 23; if (this._provider.is3idProvider) { _context16.next = 27; break; } _context16.next = 27; return this._writeAddressLink(proof); case 27: _context16.next = 32; break; case 29: _context16.prev = 29; _context16.t1 = _context16["catch"](23); throw new Error('An error occured while publishing link:', _context16.t1); case 32: _context16.next = 44; break; case 34: if (this.hasPublishedLink[proof.signature]) { _context16.next = 44; break; } // Don't want to publish on every call to _linkProfile this.hasPublishedLink[proof.signature] = true; _context16.prev = 36; _context16.next = 39; return utils.fetchJson(this._serverUrl + '/link', proof); case 39: _context16.next = 44; break; case 41: _context16.prev = 41; _context16.t2 = _context16["catch"](36); throw new Error('An error occured while publishing link:', _context16.t2); case 44: _context16.next = 46; return this["public"].get('proof_did'); case 46: proofdid = _context16.sent; if (!proofdid) { _context16.next = 60; break; } // if prior muport, re publish with 3id including muport issuer = didJWT.decodeJWT(proofdid).payload.iss; if (!issuer.includes('muport')) { _context16.next = 58; break; } jwt = { muport: proofdid }; _context16.t3 = this["public"]; _context16.next = 54; return this._3id.signJWT(jwt); case 54: _context16.t4 = _context16.sent; _context16.t5 = { noLink: true }; _context16.next = 58; return _context16.t3.set.call(_context16.t3, 'proof_did', _context16.t4, _context16.t5); case 58: _context16.next = 67; break; case 60: _context16.t6 = this["public"]; _context16.next = 63; return this._3id.signJWT(); case 63: _context16.t7 = _context16.sent; _context16.t8 = { noLink: true }; _context16.next = 67; return _context16.t6.set.call(_context16.t6, 'proof_did', _context16.t7, _context16.t8); case 67: case "end": return _context16.stop(); } } }, _callee16, this, [[7, 20], [23, 29], [36, 41]]); })); function _linkProfile() { return _linkProfile2.apply(this, arguments); } return _linkProfile; }() }, { key: "_writeRootstoreEntry", value: function () { var _writeRootstoreEntry2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee18(type, payload) { var _this5 = this; var cid, entryExist, entry, prev; return _regenerator["default"].wrap(function _callee18$(_context18) { while (1) { switch (_context18.prev = _context18.next) { case 0: _context18.next = 2; return this._ipfs.dag.put(payload); case 2: cid = _context18.sent.toBaseEncodedString(); _context18.next = 5; return this._ipfs.pin.add(cid); case 5: _context18.next = 7; return this._typeCIDExists(type, cid); case 7: entryExist = _context18.sent; if (!entryExist) { _context18.next = 10; break; } return _context18.abrupt("return"); case 10: entry = { type: type, data: cid }; // the below code prevents multiple simultaneous writes, // which orbitdb doesn't support prev = this._rootstoreQueue; this._rootstoreQueue = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee17() { return _regenerator["default"].wrap(function _callee17$(_context17) { while (1) { switch (_context17.prev = _context17.next) { case 0: if (!prev) { _context17.next = 3; break; } _context17.next = 3; return prev; case 3: _context17.next = 5; return _this5.replicator.rootstore.add(entry); case 5: case "end": return _context17.stop(); } } }, _callee17); }))(); case 13: case "end": return _context18.stop(); } } }, _callee18, this); })); function _writeRootstoreEntry(_x13, _x14) { return _writeRootstoreEntry2.apply(this, arguments); } return _writeRootstoreEntry; }() }, { key: "_typeCIDExists", value: function () { var _typeCIDExists2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee19(type, cid) { var entries, typeEntries; return _regenerator["default"].wrap(function _callee19$(_context19) { while (1) { switch (_context19.prev = _context19.next) { case 0: _context19.next = 2; return this.replicator.rootstore.iterator({ limit: -1 }).collect(); case 2: entries = _context19.sent; typeEntries = entries.filter(function (e) { return e.payload.value.type === type; }); return _context19.abrupt("return", Boolean(typeEntries.find(function (entry) { return entry.data === cid; }))); case 5: case "end": return _context19.stop(); } } }, _callee19, this); })); function _typeCIDExists(_x15, _x16) { return _typeCIDExists2.apply(this, arguments); } return _typeCIDExists; }() }, { key: "_deleteAddressLink", value: function () { var _deleteAddressLink2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee20(address) { var link; return _regenerator["default"].wrap(function _callee20$(_context20) { while (1) { switch (_context20.prev = _context20.next) { case 0: address = address.toLowerCase(); _context20.next = 3; return this._readAddressLink(address); case 3: link = _context20.sent; if (link) { _context20.next = 6; break; } throw new Error('_deleteAddressLink: link for given address does not exist'); case 6: return _context20.abrupt("return", this.replicator.rootstore.remove(link.entry.hash)); case 7: case "end": return _context20.stop(); } } }, _callee20, this); })); function _deleteAddressLink(_x17) { return _deleteAddressLink2.apply(this, arguments); } return _deleteAddressLink; }() }, { key: "_readAddressLinks", value: function () { var _readAddressLinks2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee21() { var links, allLinks; return _regenerator["default"].wrap(function _callee21$(_context21) { while (1) { switch (_context21.prev = _context21.next) { case 0: _context21.next = 2; return this.replicator.getAddressLinks(); case 2: links = _context21.sent; _context21.next = 5; return Promise.all(links.map(validateLink)); case 5: allLinks = _context21.sent; return _context21.abrupt("return", allLinks.filter(Boolean)); case 7: case "end": return _context21.stop(); } } }, _callee21, this); })); function _readAddressLinks() { return _readAddressLinks2.apply(this, arguments); } return _readAddressLinks; }() }, { key: "_readAddressLink", value: function () { var _readAddressLink2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee22(address) { var links; return _regenerator["default"].wrap(function _callee22$(_context22) { while (1) { switch (_context22.prev = _context22.next) { case 0: address = address.toLowerCase(); _context22.next = 3; return this._readAddressLinks(); case 3: links = _context22.sent; return _context22.abrupt("return", links.find(function (link) { return link.address.toLowerCase() === address; })); case 5: case "end": return _context22.stop(); } } }, _callee22, this); })); function _readAddressLink(_x18) { return _readAddressLink2.apply(this, arguments); } return _readAddressLink; }() }, { key: "close", value: function () { var _close = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee23() { return _regenerator