{"version":3,"sources":["webpack:///index.js","webpack:///webpack/bootstrap 83cd2a562153e7e829c5","webpack:///external \"winston\"","webpack:///./config/siteConfig.js","webpack:///./server/models/index.js","webpack:///external \"sequelize\"","webpack:///./config/mysqlConfig.js","webpack:///./server/helpers/sequelizeHelpers.js","webpack:///./server/helpers/lbryApi.js","webpack:///./server/helpers/googleAnalytics.js","webpack:///./server/helpers/publishHelpers.js","webpack:///external \"babel-polyfill\"","webpack:///external \"whatwg-fetch\"","webpack:///./speech.js","webpack:///./server/routes/apiRoutes.js","webpack:///./server/models/certificate.js","webpack:///./server/models/channel.js","webpack:///./server/models/claim.js","webpack:///./server/models/file.js","webpack:///./server/models/request.js","webpack:///./server/models/user.js","webpack:///external \"bcrypt\"","webpack:///./server/controllers/publishController.js","webpack:///external \"axios\"","webpack:///./config/lbryConfig.js","webpack:///external \"universal-analytics\"","webpack:///external \"fs\"","webpack:///./server/helpers/errorHandlers.js","webpack:///./server/auth/authentication.js","webpack:///./server/controllers/serveController.js","webpack:///./server/helpers/channelPagination.js","webpack:///./config/loggerConfig.js","webpack:///./config/slackConfig.js","webpack:///external \"winston-slack-webhook\""],"names":["module","exports","modules","__webpack_require__","moduleId","installedModules","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","require","SiteConfig","_this","this","analytics","googleId","assetDefaults","description","thumbnail","title","auth","sessionKey","customComponents","components","containers","pages","details","host","port","twitter","publishing","additionalClaimAddresses","disabled","disabledMessage","primaryClaimAddress","thumbnailChannel","thumbnailChannelId","uploadDirectory","configure","config","console","log","Sequelize","logger","info","_require","database","username","password","db","sequelize","dialect","dialectOptions","decimalNumbers","logging","pool","max","min","idle","acquire","authenticate","then","catch","err","error","Certificate","Channel","Claim","File","Request","User","import","keys","forEach","modelName","associate","upsert","Model","values","condition","tableName","findOne","where","obj","debug","update","create","mysql","returnShortId","claimsArray","longId","claimIndex","shortId","substring","shortIdLength","findIndex","element","claimId","Error","possibleMatches","slice","length","filter","axios","_require$api","api","apiHost","apiPort","lbryApiUri","_require2","chooseGaLbrynetPublishLabel","sendGATimingEvent","handleLbrynetResponse","_ref","resolve","reject","data","result","JSON","stringify","publishClaim","publishParams","gaStartTime","Date","now","Promise","post","method","params","response","getClaim","uri","timeout","getClaimList","claimName","resolveUri","_ref2","getDownloadDirectory","_ref3","download_directory","createChannel","channel_name","amount","createServeEventParams","headers","ip","originalUrl","eventCategory","eventAction","eventLabel","ipOverride","userAgentOverride","createPublishTimingEventParams","category","variable","label","startTime","endTime","userTimingCategory","userTimingVariableName","userTimingTime","userTimingLabel","sendGoogleAnalyticsEvent","visitorId","replace","ua","strictCidFormat","https","event","sendGoogleAnalyticsTiming","timing","sendGAServeEvent","channelName","channelId","channel_id","fs","parsePublishApiRequestBody","nsfw","license","exec","parsePublishApiRequestFiles","file","path","type","size","test","validateFileTypeAndSize","fileName","filePath","fileType","thumbnailFileName","thumbnailFilePath","thumbnailFileType","createBasicPublishParams","trim","file_path","bid","metadata","author","language","claim_address","createThumbnailPublishParams","deleteTemporaryFile","unlink","addGetResultsToFileData","fileInfo","getResult","file_name","download_path","createFileData","outpoint","height","address","contentType","apiRoutes","slack","localLoginStrategy","e","code","localSignupStrategy","passport","_slicedToArray","sliceIterator","arr","_arr","_n","_d","_e","undefined","_s","_i","Symbol","iterator","next","done","push","value","Array","isArray","TypeError","claimNameIsAvailable","checkChannelAvailability","publish","_require3","_require4","errorHandlers","_require5","_require6","authenticateUser","_require7","getChannelData","getChannelClaims","getClaimId","channelAvailabilityRoute","res","availableName","status","json","handleErrorResponse","channelShortIdRoute","getShortChannelIdFromLongChannelId","channelDataRoute","body","channelClaimId","success","message","channelClaimsRoute","_ref4","page","claimListRoute","_ref5","claimsList","claimGetRoute","_ref6","resolveClaim","resolveResult","fileData","all","_ref7","_ref8","_ref9","_ref10","_ref10$","completed","claimAvailabilityRoute","_ref11","claimResolveRoute","_ref12","resolvedUri","claimPublishRoute","_ref13","files","user","channelPassword","_parsePublishApiReque","_parsePublishApiReque2","_ref14","_ref15","_ref15$","thumbnailPublishParams","claim_id","url","lbryTx","claimShortIdRoute","_ref16","getShortClaimIdFromLongClaimId","claimLongIdRoute","_ref17","claimDataRoute","_ref18","claimInfo","fileAvailabilityRoute","_ref19","STRING","BOOLEAN","INTEGER","TEXT","DECIMAL","define","default","claimSequence","decodedClaim","depth","effectiveAmount","hasSignature","hex","nout","txid","validAtHeight","valueVersion","claimType","certificateVersion","keyType","publicKey","freezeTableName","belongsTo","foreignKey","allowNull","longChannelId","findAll","order","getLongChannelIdFromShortChannelId","_this2","$like","getLongChannelIdFromChannelName","_this3","validateLongChannelId","_this4","getLongChannelId","hasOne","determineFileExtensionFromContentType","determineThumbnail","storedThumbnail","defaultThumbnail","prepareClaimData","claim","certificateId","licenseUrl","preview","metadataVersion","source","sourceType","sourceVersion","streamVersion","getAllChannelClaims","raw","channelClaimsArray","getClaimIdByLongChannelId","getLongClaimIdFromShortClaimId","getTopFreeClaimIdByClaimName","_this5","dataValues","validateLongClaimId","_this6","getLongClaimId","_this7","claimArray","defaultValue","trendingEligible","hasMany","getRecentClaims","limit","action","ipAddress","bcrypt","userName","comparePassword","compare","changePassword","newPassword","genSalt","saltError","salt","hash","hashError","hook","options","_defineProperty","key","writable","lbryApi","publishHelpers","_require$publishing","Op","publishResults","tx","channel","fileRecord","claimRecord","upsertCriteria","setClaim","setFile","claimAddresses","attributes","or","lbryConfig","useObjectPropertiesIfNoKeys","_module$exports$retur","returnErrorMessageAndStatus","_module$exports$retur2","createErrorResponsePayload","newErrorObject","getOwnPropertyNames","authenticateChannelCredentials","userPassword","channelData","channelFindParams","isMatch","returnPaginatedChannelClaims","getClaimIdByChannel","getClaimIdByClaim","longClaimId","longChannelClaimId","shortChannelClaimId","paginatedChannelViewData","getLocalFileRecord","claims","totalPages","determineTotalPages","paginationPage","getPageFromQuery","extractPageFromClaims","previousPage","determinePreviousPage","currentPage","nextPage","determineNextPage","totalResults","determineTotalClaims","parseInt","pageNumber","claimStartIndex","claimEndIndex","totalClaims","fullPages","Math","floor","LoggerConfig","logLevel","transports","Console","level","timestamp","colorize","prettyPrint","handleExceptions","humanReadableUnhandledException","warn","verbose","silly","SlackConfig","slackWebHook","slackErrorChannel","slackInfoChannel","winston","add","winstonSlackWebHook","webhookUrl","iconEmoji","SlackWebHook"],"mappings":"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","file":"index.js","sourcesContent":["module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 9);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"winston\");\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction SiteConfig() {\n var _this = this;\n\n this.analytics = {\n googleId: 'default'\n };\n this.assetDefaults = {\n description: 'An asset published on Spee.ch',\n thumbnail: 'https://spee.ch/assets/img/video_thumb_default.png',\n title: 'Spee.ch'\n };\n this.auth = {\n sessionKey: 'default'\n };\n this.customComponents = {\n components: {},\n containers: {},\n pages: {}\n };\n this.details = {\n description: 'Open-source, decentralized image and video sharing.',\n host: 'default',\n port: 3000,\n title: 'Spee.ch',\n twitter: '@spee_ch'\n };\n this.publishing = {\n additionalClaimAddresses: [],\n disabled: false,\n disabledMessage: 'Please check back soon.',\n primaryClaimAddress: 'default',\n thumbnailChannel: 'default',\n thumbnailChannelId: 'default',\n uploadDirectory: '/home/lbry/Uploads'\n };\n this.configure = function (config) {\n if (!config) {\n return console.log('No site config received.');\n }\n var analytics = config.analytics,\n assetDefaults = config.assetDefaults,\n auth = config.auth,\n customComponents = config.customComponents,\n details = config.details,\n publishing = config.publishing;\n\n _this.analytics = analytics;\n _this.assetDefaults = assetDefaults;\n _this.auth = auth;\n _this.details = details;\n _this.publishing = publishing;\n _this.customComponents = customComponents;\n };\n};\n\nmodule.exports = new SiteConfig();\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar Sequelize = __webpack_require__(3);\nvar logger = __webpack_require__(0);\n\nlogger.info('exporting sequelize models');\n\nvar _require = __webpack_require__(4),\n database = _require.database,\n username = _require.username,\n password = _require.password;\n\nvar db = {};\n// set sequelize options\nvar sequelize = new Sequelize(database, username, password, {\n host: 'localhost',\n dialect: 'mysql',\n dialectOptions: { decimalNumbers: true }, // fix to ensure DECIMAL will not be stored as a string\n logging: false,\n pool: {\n max: 5,\n min: 0,\n idle: 10000,\n acquire: 10000\n }\n});\n\n// establish mysql connection\nsequelize.authenticate().then(function () {\n logger.info('Sequelize has established mysql connection successfully.');\n}).catch(function (err) {\n logger.error('Sequelize was unable to connect to the database:', err);\n});\n\n// manually add each model to the db object\nvar Certificate = __webpack_require__(14);\nvar Channel = __webpack_require__(15);\nvar Claim = __webpack_require__(16);\nvar File = __webpack_require__(17);\nvar Request = __webpack_require__(18);\nvar User = __webpack_require__(19);\ndb['Certificate'] = sequelize.import('Certificate', Certificate);\ndb['Channel'] = sequelize.import('Channel', Channel);\ndb['Claim'] = sequelize.import('Claim', Claim);\ndb['File'] = sequelize.import('File', File);\ndb['Request'] = sequelize.import('Request', Request);\ndb['User'] = sequelize.import('User', User);\n\n// run model.association for each model in the db object that has an association\nObject.keys(db).forEach(function (modelName) {\n if (db[modelName].associate) {\n logger.info('Associating model:', modelName);\n db[modelName].associate(db);\n }\n});\n\ndb.sequelize = sequelize;\ndb.Sequelize = Sequelize;\n\n// add an 'upsert' method to the db object\ndb.upsert = function (Model, values, condition, tableName) {\n return Model.findOne({\n where: condition\n }).then(function (obj) {\n if (obj) {\n // update\n logger.debug('updating record in db.' + tableName);\n return obj.update(values);\n } else {\n // insert\n logger.debug('creating record in db.' + tableName);\n return Model.create(values);\n }\n }).catch(function (error) {\n logger.error(tableName + '.upsert error', error);\n throw error;\n });\n};\n\nmodule.exports = db;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"sequelize\");\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction mysql() {\n var _this = this;\n\n this.database = 'default';\n this.username = 'default';\n this.password = 'default';\n this.configure = function (config) {\n if (!config) {\n return console.log('No MySQL config received.');\n }\n var database = config.database,\n username = config.username,\n password = config.password;\n\n _this.database = database;\n _this.username = username;\n _this.password = password;\n };\n};\n\nmodule.exports = new mysql();\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = {\n returnShortId: function returnShortId(claimsArray, longId) {\n var claimIndex = void 0;\n var shortId = longId.substring(0, 1); // default short id is the first letter\n var shortIdLength = 0;\n // find the index of this claim id\n claimIndex = claimsArray.findIndex(function (element) {\n return element.claimId === longId;\n });\n if (claimIndex < 0) {\n throw new Error('claim id not found in claims list');\n }\n // get an array of all claims with lower height\n var possibleMatches = claimsArray.slice(0, claimIndex);\n // remove certificates with the same prefixes until none are left.\n while (possibleMatches.length > 0) {\n shortIdLength += 1;\n shortId = longId.substring(0, shortIdLength);\n possibleMatches = possibleMatches.filter(function (element) {\n return element.claimId && element.claimId.substring(0, shortIdLength) === shortId;\n });\n }\n return shortId;\n }\n};\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar axios = __webpack_require__(22);\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(23),\n _require$api = _require.api,\n apiHost = _require$api.apiHost,\n apiPort = _require$api.apiPort;\n\nvar lbryApiUri = 'http://' + apiHost + ':' + apiPort;\n\nvar _require2 = __webpack_require__(7),\n chooseGaLbrynetPublishLabel = _require2.chooseGaLbrynetPublishLabel,\n sendGATimingEvent = _require2.sendGATimingEvent;\n\nvar handleLbrynetResponse = function handleLbrynetResponse(_ref, resolve, reject) {\n var data = _ref.data;\n\n logger.debug('lbry api data:', data);\n if (data.result) {\n // check for an error\n if (data.result.error) {\n logger.debug('Lbrynet api error:', data.result.error);\n reject(new Error(data.result.error));\n return;\n };\n resolve(data.result);\n return;\n }\n // fallback in case it just timed out\n reject(JSON.stringify(data));\n};\n\nmodule.exports = {\n publishClaim: function publishClaim(publishParams) {\n logger.debug('lbryApi >> Publishing claim to \"' + publishParams.name + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'publish',\n params: publishParams\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaim: function getClaim(uri) {\n logger.debug('lbryApi >> Getting Claim for \"' + uri + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'get',\n params: { uri: uri, timeout: 20 }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaimList: function getClaimList(claimName) {\n logger.debug('lbryApi >> Getting claim_list for \"' + claimName + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'claim_list',\n params: { name: claimName }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n resolveUri: function resolveUri(uri) {\n logger.debug('lbryApi >> Resolving URI for \"' + uri + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'resolve',\n params: { uri: uri }\n }).then(function (_ref2) {\n var data = _ref2.data;\n\n sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());\n if (data.result[uri].error) {\n // check for errors\n reject(data.result[uri].error);\n } else {\n // if no errors, resolve\n resolve(data.result[uri]);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getDownloadDirectory: function getDownloadDirectory() {\n logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'settings_get'\n }).then(function (_ref3) {\n var data = _ref3.data;\n\n sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());\n if (data.result) {\n resolve(data.result.download_directory);\n } else {\n return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');\n }\n }).catch(function (error) {\n logger.error('Lbrynet Error:', error);\n resolve('/home/lbry/Downloads/');\n });\n });\n },\n createChannel: function createChannel(name) {\n logger.debug('lbryApi >> Creating channel for ' + name + '...');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'channel_new',\n params: {\n channel_name: name,\n amount: 0.1\n }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n }\n};\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\nvar ua = __webpack_require__(24);\n\nvar _require = __webpack_require__(1),\n googleId = _require.analytics.googleId,\n title = _require.details.title;\n\nfunction createServeEventParams(headers, ip, originalUrl) {\n return {\n eventCategory: 'client requests',\n eventAction: 'serve request',\n eventLabel: originalUrl,\n ipOverride: ip,\n userAgentOverride: headers['user-agent']\n };\n};\n\nfunction createPublishTimingEventParams(category, variable, label, startTime, endTime) {\n var duration = endTime - startTime;\n return {\n userTimingCategory: category,\n userTimingVariableName: variable,\n userTimingTime: duration,\n userTimingLabel: label\n };\n};\n\nfunction sendGoogleAnalyticsEvent(ip, params) {\n var visitorId = ip.replace(/\\./g, '-');\n var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.event(params, function (err) {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n });\n};\n\nfunction sendGoogleAnalyticsTiming(visitorId, params) {\n var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.timing(params, function (err) {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n logger.debug('Timing event successfully sent to google analytics');\n });\n};\n\nmodule.exports = {\n sendGAServeEvent: function sendGAServeEvent(headers, ip, originalUrl) {\n var params = createServeEventParams(headers, ip, originalUrl);\n sendGoogleAnalyticsEvent(ip, params);\n },\n sendGATimingEvent: function sendGATimingEvent(category, variable, label, startTime, endTime) {\n var params = createPublishTimingEventParams(category, variable, label, startTime, endTime);\n sendGoogleAnalyticsTiming(title, params);\n },\n chooseGaLbrynetPublishLabel: function chooseGaLbrynetPublishLabel(_ref) {\n var channelName = _ref.channel_name,\n channelId = _ref.channel_id;\n\n return channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM';\n }\n};\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\nvar fs = __webpack_require__(25);\n\nvar _require = __webpack_require__(1),\n details = _require.details,\n publishing = _require.publishing;\n\nmodule.exports = {\n parsePublishApiRequestBody: function parsePublishApiRequestBody(_ref) {\n var name = _ref.name,\n nsfw = _ref.nsfw,\n license = _ref.license,\n title = _ref.title,\n description = _ref.description,\n thumbnail = _ref.thumbnail;\n\n // validate name\n if (!name) {\n throw new Error('no name field found in request');\n }\n var invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);\n if (invalidNameCharacters) {\n throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and \"-\"');\n }\n // optional parameters\n nsfw = nsfw === 'true';\n license = license || null;\n title = title || null;\n description = description || null;\n thumbnail = thumbnail || null;\n // return results\n return {\n name: name,\n nsfw: nsfw,\n license: license,\n title: title,\n description: description,\n thumbnail: thumbnail\n };\n },\n parsePublishApiRequestFiles: function parsePublishApiRequestFiles(_ref2) {\n var file = _ref2.file,\n thumbnail = _ref2.thumbnail;\n\n // make sure a file was provided\n if (!file) {\n throw new Error('no file with key of [file] found in request');\n }\n if (!file.path) {\n throw new Error('no file path found');\n }\n if (!file.type) {\n throw new Error('no file type found');\n }\n if (!file.size) {\n throw new Error('no file type found');\n }\n // validate the file name\n if (/'/.test(file.name)) {\n throw new Error('apostrophes are not allowed in the file name');\n }\n // validate the file\n module.exports.validateFileTypeAndSize(file);\n // return results\n return {\n fileName: file.name,\n filePath: file.path,\n fileType: file.type,\n thumbnailFileName: thumbnail ? thumbnail.name : null,\n thumbnailFilePath: thumbnail ? thumbnail.path : null,\n thumbnailFileType: thumbnail ? thumbnail.type : null\n };\n },\n validateFileTypeAndSize: function validateFileTypeAndSize(file) {\n // check file type and size\n switch (file.type) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n if (file.size > 10000000) {\n logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .gif was too big');\n throw new Error('Sorry, .gifs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .mp4 was too big');\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n logger.debug('publish > file validation > unrecognized file type');\n throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n return file;\n },\n createBasicPublishParams: function createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail) {\n logger.debug('Creating Publish Parameters');\n // provide defaults for title\n if (title === null || title.trim() === '') {\n title = name;\n }\n // provide default for description\n if (description === null || description.trim() === '') {\n description = '';\n }\n // provide default for license\n if (license === null || license.trim() === '') {\n license = ' '; // default to empty string\n }\n // create the publish params\n var publishParams = {\n name: name,\n file_path: filePath,\n bid: 0.01,\n metadata: {\n description: description,\n title: title,\n author: details.title,\n language: 'en',\n license: license,\n nsfw: nsfw\n },\n claim_address: publishing.primaryClaimAddress\n };\n // add thumbnail to channel if video\n if (thumbnail) {\n publishParams['metadata']['thumbnail'] = thumbnail;\n }\n return publishParams;\n },\n createThumbnailPublishParams: function createThumbnailPublishParams(thumbnailFilePath, claimName, license, nsfw) {\n if (!thumbnailFilePath) {\n return;\n }\n logger.debug('Creating Thumbnail Publish Parameters');\n // create the publish params\n return {\n name: claimName + '-thumb',\n file_path: thumbnailFilePath,\n bid: 0.01,\n metadata: {\n title: claimName + ' thumbnail',\n description: 'a thumbnail for ' + claimName,\n author: details.title,\n language: 'en',\n license: license,\n nsfw: nsfw\n },\n claim_address: publishing.primaryClaimAddress,\n channel_name: publishing.thumbnailChannel,\n channel_id: publishing.thumbnailChannelId\n };\n },\n deleteTemporaryFile: function deleteTemporaryFile(filePath) {\n fs.unlink(filePath, function (err) {\n if (err) {\n logger.error('error deleting temporary file ' + filePath);\n throw err;\n }\n logger.debug('successfully deleted ' + filePath);\n });\n },\n addGetResultsToFileData: function addGetResultsToFileData(fileInfo, getResult) {\n fileInfo.fileName = getResult.file_name;\n fileInfo.filePath = getResult.download_path;\n return fileInfo;\n },\n createFileData: function createFileData(_ref3) {\n var name = _ref3.name,\n claimId = _ref3.claimId,\n outpoint = _ref3.outpoint,\n height = _ref3.height,\n address = _ref3.address,\n nsfw = _ref3.nsfw,\n contentType = _ref3.contentType;\n\n return {\n name: name,\n claimId: claimId,\n outpoint: outpoint,\n height: height,\n address: address,\n fileName: '',\n filePath: '',\n fileType: contentType,\n nsfw: nsfw\n };\n }\n};\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(10);\n__webpack_require__(11);\nmodule.exports = __webpack_require__(12);\n\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"babel-polyfill\");\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"whatwg-fetch\");\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n// const Server = require('./server/server.js');\n// const Components = require('./client/components');\n// const Containers = require('./client/containers');\n// const Pages = require('./client/pages');\nvar apiRoutes = __webpack_require__(13);\nvar logger = __webpack_require__(30);\nvar mysql = __webpack_require__(4);\nvar slack = __webpack_require__(31);\nvar database = __webpack_require__(2);\nvar localLoginStrategy = __webpack_require__(!(function webpackMissingModule() { var e = new Error(\"Cannot find module \\\"./passport/local-login.js\\\"\"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));\nvar localSignupStrategy = __webpack_require__(!(function webpackMissingModule() { var e = new Error(\"Cannot find module \\\"./passport/local-signup.js\\\"\"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));\n\nvar _exports = {\n // Server,\n // Components,\n // Containers,\n // Pages,\n apiRoutes: apiRoutes,\n config: {\n logger: logger,\n mysql: mysql,\n slack: slack\n },\n database: database,\n passport: {\n localLoginStrategy: localLoginStrategy,\n localSignupStrategy: localSignupStrategy\n }\n};\n\nmodule.exports = _exports;\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(1),\n host = _require.details.host;\n\nvar db = __webpack_require__(2);\n\nvar _require2 = __webpack_require__(21),\n claimNameIsAvailable = _require2.claimNameIsAvailable,\n checkChannelAvailability = _require2.checkChannelAvailability,\n publish = _require2.publish;\n\nvar _require3 = __webpack_require__(6),\n getClaimList = _require3.getClaimList,\n resolveUri = _require3.resolveUri,\n getClaim = _require3.getClaim;\n\nvar _require4 = __webpack_require__(8),\n addGetResultsToFileData = _require4.addGetResultsToFileData,\n createBasicPublishParams = _require4.createBasicPublishParams,\n createThumbnailPublishParams = _require4.createThumbnailPublishParams,\n parsePublishApiRequestBody = _require4.parsePublishApiRequestBody,\n parsePublishApiRequestFiles = _require4.parsePublishApiRequestFiles,\n createFileData = _require4.createFileData;\n\nvar errorHandlers = __webpack_require__(26);\n\nvar _require5 = __webpack_require__(7),\n sendGATimingEvent = _require5.sendGATimingEvent;\n\nvar _require6 = __webpack_require__(27),\n authenticateUser = _require6.authenticateUser;\n\nvar _require7 = __webpack_require__(28),\n getChannelData = _require7.getChannelData,\n getChannelClaims = _require7.getChannelClaims,\n getClaimId = _require7.getClaimId;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\n\nmodule.exports = {\n // route to check whether site has published to a channel\n channelAvailabilityRoute: function channelAvailabilityRoute(_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n name = _ref.params.name;\n\n var gaStartTime = Date.now();\n checkChannelAvailability(name).then(function (availableName) {\n res.status(200).json(availableName);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to get a short channel id from long channel Id\n channelShortIdRoute: function channelShortIdRoute(_ref2, res) {\n var ip = _ref2.ip,\n originalUrl = _ref2.originalUrl,\n params = _ref2.params;\n\n db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name).then(function (shortId) {\n res.status(200).json(shortId);\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n channelDataRoute: function channelDataRoute(_ref3, res) {\n var ip = _ref3.ip,\n originalUrl = _ref3.originalUrl,\n body = _ref3.body,\n params = _ref3.params;\n\n var channelName = params.channelName;\n var channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n getChannelData(channelName, channelClaimId, 0).then(function (data) {\n if (data === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel was found' });\n }\n res.status(200).json({ success: true, data: data });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n channelClaimsRoute: function channelClaimsRoute(_ref4, res) {\n var ip = _ref4.ip,\n originalUrl = _ref4.originalUrl,\n body = _ref4.body,\n params = _ref4.params;\n\n var channelName = params.channelName;\n var channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n var page = params.page;\n getChannelClaims(channelName, channelClaimId, page).then(function (data) {\n if (data === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel was found' });\n }\n res.status(200).json({ success: true, data: data });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to run a claim_list request on the daemon\n claimListRoute: function claimListRoute(_ref5, res) {\n var ip = _ref5.ip,\n originalUrl = _ref5.originalUrl,\n params = _ref5.params;\n\n getClaimList(params.name).then(function (claimsList) {\n res.status(200).json(claimsList);\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to get an asset\n claimGetRoute: function claimGetRoute(_ref6, res) {\n var ip = _ref6.ip,\n originalUrl = _ref6.originalUrl,\n params = _ref6.params;\n\n var name = params.name;\n var claimId = params.claimId;\n // resolve the claim\n db.Claim.resolveClaim(name, claimId).then(function (resolveResult) {\n // make sure a claim actually exists at that uri\n if (!resolveResult) {\n throw new Error('No matching uri found in Claim table');\n }\n var fileData = createFileData(resolveResult);\n // get the claim\n return Promise.all([fileData, getClaim(name + '#' + claimId)]);\n }).then(function (_ref7) {\n var _ref8 = _slicedToArray(_ref7, 2),\n fileData = _ref8[0],\n getResult = _ref8[1];\n\n fileData = addGetResultsToFileData(fileData, getResult);\n return Promise.all([db.upsert(db.File, fileData, { name: name, claimId: claimId }, 'File'), getResult]);\n }).then(function (_ref9) {\n var _ref10 = _slicedToArray(_ref9, 2),\n fileRecord = _ref10[0],\n _ref10$ = _ref10[1],\n message = _ref10$.message,\n completed = _ref10$.completed;\n\n res.status(200).json({ success: true, message: message, completed: completed });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to check whether this site published to a claim\n claimAvailabilityRoute: function claimAvailabilityRoute(_ref11, res) {\n var ip = _ref11.ip,\n originalUrl = _ref11.originalUrl,\n name = _ref11.params.name;\n\n var gaStartTime = Date.now();\n claimNameIsAvailable(name).then(function (result) {\n res.status(200).json(result);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to run a resolve request on the daemon\n claimResolveRoute: function claimResolveRoute(_ref12, res) {\n var headers = _ref12.headers,\n ip = _ref12.ip,\n originalUrl = _ref12.originalUrl,\n params = _ref12.params;\n\n resolveUri(params.name + '#' + params.claimId).then(function (resolvedUri) {\n res.status(200).json(resolvedUri);\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to run a publish request on the daemon\n claimPublishRoute: function claimPublishRoute(_ref13, res) {\n var body = _ref13.body,\n files = _ref13.files,\n headers = _ref13.headers,\n ip = _ref13.ip,\n originalUrl = _ref13.originalUrl,\n user = _ref13.user;\n\n // define variables\n var channelName = void 0,\n channelId = void 0,\n channelPassword = void 0,\n description = void 0,\n fileName = void 0,\n filePath = void 0,\n fileType = void 0,\n gaStartTime = void 0,\n license = void 0,\n name = void 0,\n nsfw = void 0,\n thumbnail = void 0,\n thumbnailFileName = void 0,\n thumbnailFilePath = void 0,\n thumbnailFileType = void 0,\n title = void 0;\n // record the start time of the request\n gaStartTime = Date.now();\n // validate the body and files of the request\n try {\n var _parsePublishApiReque = parsePublishApiRequestBody(body);\n // validateApiPublishRequest(body, files);\n\n\n name = _parsePublishApiReque.name;\n nsfw = _parsePublishApiReque.nsfw;\n license = _parsePublishApiReque.license;\n title = _parsePublishApiReque.title;\n description = _parsePublishApiReque.description;\n thumbnail = _parsePublishApiReque.thumbnail;\n\n var _parsePublishApiReque2 = parsePublishApiRequestFiles(files);\n\n fileName = _parsePublishApiReque2.fileName;\n filePath = _parsePublishApiReque2.filePath;\n fileType = _parsePublishApiReque2.fileType;\n thumbnailFileName = _parsePublishApiReque2.thumbnailFileName;\n thumbnailFilePath = _parsePublishApiReque2.thumbnailFilePath;\n thumbnailFileType = _parsePublishApiReque2.thumbnailFileType;\n channelName = body.channelName;\n channelId = body.channelId;\n channelPassword = body.channelPassword;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n // check channel authorization\n Promise.all([authenticateUser(channelName, channelId, channelPassword, user), claimNameIsAvailable(name), createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail), createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw)]).then(function (_ref14) {\n var _ref15 = _slicedToArray(_ref14, 4),\n _ref15$ = _ref15[0],\n channelName = _ref15$.channelName,\n channelClaimId = _ref15$.channelClaimId,\n validatedClaimName = _ref15[1],\n publishParams = _ref15[2],\n thumbnailPublishParams = _ref15[3];\n\n // add channel details to the publish params\n if (channelName && channelClaimId) {\n publishParams['channel_name'] = channelName;\n publishParams['channel_id'] = channelClaimId;\n }\n // publish the thumbnail\n if (thumbnailPublishParams) {\n publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);\n }\n // publish the asset\n return publish(publishParams, fileName, fileType);\n }).then(function (result) {\n res.status(200).json({\n success: true,\n message: 'publish completed successfully',\n data: {\n name: name,\n claimId: result.claim_id,\n url: host + '/' + result.claim_id + '/' + name,\n lbryTx: result\n }\n });\n // record the publish end time and send to google analytics\n sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to get a short claim id from long claim Id\n claimShortIdRoute: function claimShortIdRoute(_ref16, res) {\n var ip = _ref16.ip,\n originalUrl = _ref16.originalUrl,\n body = _ref16.body,\n params = _ref16.params;\n\n db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name).then(function (shortId) {\n res.status(200).json({ success: true, data: shortId });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n claimLongIdRoute: function claimLongIdRoute(_ref17, res) {\n var ip = _ref17.ip,\n originalUrl = _ref17.originalUrl,\n body = _ref17.body,\n params = _ref17.params;\n\n logger.debug('body:', body);\n var channelName = body.channelName;\n var channelClaimId = body.channelClaimId;\n var claimName = body.claimName;\n var claimId = body.claimId;\n getClaimId(channelName, channelClaimId, claimName, claimId).then(function (result) {\n if (result === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel could be found' });\n }\n if (result === NO_CLAIM) {\n return res.status(404).json({ success: false, message: 'No matching claim id could be found' });\n }\n res.status(200).json({ success: true, data: result });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n claimDataRoute: function claimDataRoute(_ref18, res) {\n var ip = _ref18.ip,\n originalUrl = _ref18.originalUrl,\n body = _ref18.body,\n params = _ref18.params;\n\n var claimName = params.claimName;\n var claimId = params.claimId;\n if (claimId === 'none') claimId = null;\n db.Claim.resolveClaim(claimName, claimId).then(function (claimInfo) {\n if (!claimInfo) {\n return res.status(404).json({ success: false, message: 'No claim could be found' });\n }\n res.status(200).json({ success: true, data: claimInfo });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n\n // route to see if asset is available locally\n fileAvailabilityRoute: function fileAvailabilityRoute(_ref19, res) {\n var ip = _ref19.ip,\n originalUrl = _ref19.originalUrl,\n params = _ref19.params;\n\n var name = params.name;\n var claimId = params.claimId;\n db.File.findOne({ where: { name: name, claimId: claimId } }).then(function (result) {\n if (result) {\n return res.status(200).json({ success: true, data: true });\n }\n res.status(200).json({ success: true, data: false });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n }\n};\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(5),\n returnShortId = _require.returnShortId;\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER,\n TEXT = _ref.TEXT,\n DECIMAL = _ref.DECIMAL;\n\n var Certificate = sequelize.define('Certificate', {\n address: {\n type: STRING,\n default: null\n },\n amount: {\n type: DECIMAL(19, 8),\n default: null\n },\n claimId: {\n type: STRING,\n default: null\n },\n claimSequence: {\n type: INTEGER,\n default: null\n },\n decodedClaim: {\n type: BOOLEAN,\n default: null\n },\n depth: {\n type: INTEGER,\n default: null\n },\n effectiveAmount: {\n type: DECIMAL(19, 8),\n default: null\n },\n hasSignature: {\n type: BOOLEAN,\n default: null\n },\n height: {\n type: INTEGER,\n default: null\n },\n hex: {\n type: TEXT('long'),\n default: null\n },\n name: {\n type: STRING,\n default: null\n },\n nout: {\n type: INTEGER,\n default: null\n },\n txid: {\n type: STRING,\n default: null\n },\n validAtHeight: {\n type: INTEGER,\n default: null\n },\n outpoint: {\n type: STRING,\n default: null\n },\n valueVersion: {\n type: STRING,\n default: null\n },\n claimType: {\n type: STRING,\n default: null\n },\n certificateVersion: {\n type: STRING,\n default: null\n },\n keyType: {\n type: STRING,\n default: null\n },\n publicKey: {\n type: TEXT('long'),\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Certificate.associate = function (db) {\n Certificate.belongsTo(db.Channel, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {\n var _this = this;\n\n logger.debug('getShortChannelIdFromLongChannelId ' + channelName + ':' + longChannelId);\n return new Promise(function (resolve, reject) {\n _this.findAll({\n where: { name: channelName },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n throw new Error('No channel(s) found with that channel name');\n default:\n return resolve(returnShortId(result, longChannelId));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {\n var _this2 = this;\n\n logger.debug('getLongChannelIdFromShortChannelId(' + channelName + ', ' + channelClaimId + ')');\n return new Promise(function (resolve, reject) {\n _this2.findAll({\n where: {\n name: channelName,\n claimId: {\n $like: channelClaimId + '%'\n }\n },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n // note results must be sorted\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromChannelName = function (channelName) {\n var _this3 = this;\n\n logger.debug('getLongChannelIdFromChannelName(' + channelName + ')');\n return new Promise(function (resolve, reject) {\n _this3.findAll({\n where: { name: channelName },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.validateLongChannelId = function (name, claimId) {\n var _this4 = this;\n\n logger.debug('validateLongChannelId(' + name + ', ' + claimId + ')');\n return new Promise(function (resolve, reject) {\n _this4.findOne({\n where: { name: name, claimId: claimId }\n }).then(function (result) {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelId = function (channelName, channelClaimId) {\n logger.debug('getLongChannelId(' + channelName + ', ' + channelClaimId + ')');\n if (channelClaimId && channelClaimId.length === 40) {\n // if a full channel id is provided\n return this.validateLongChannelId(channelName, channelClaimId);\n } else if (channelClaimId && channelClaimId.length < 40) {\n // if a short channel id is provided\n return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);\n } else {\n return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided\n }\n };\n\n return Certificate;\n};\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING;\n\n var Channel = sequelize.define('Channel', {\n channelName: {\n type: STRING,\n allowNull: false\n },\n channelClaimId: {\n type: STRING,\n allowNull: false\n }\n }, {\n freezeTableName: true\n });\n\n Channel.associate = function (db) {\n Channel.belongsTo(db.User);\n Channel.hasOne(db.Certificate);\n };\n\n return Channel;\n};\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(5),\n returnShortId = _require.returnShortId;\n\nvar _require2 = __webpack_require__(1),\n defaultThumbnail = _require2.assetDefaults.thumbnail,\n host = _require2.details.host;\n\nfunction determineFileExtensionFromContentType(contentType) {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n return 'jpeg';\n case 'image/png':\n return 'png';\n case 'image/gif':\n return 'gif';\n case 'video/mp4':\n return 'mp4';\n default:\n logger.debug('setting unknown file type as file extension jpeg');\n return 'jpeg';\n }\n};\n\nfunction determineThumbnail(storedThumbnail, defaultThumbnail) {\n if (storedThumbnail === '') {\n return defaultThumbnail;\n }\n return storedThumbnail;\n};\n\nfunction prepareClaimData(claim) {\n // logger.debug('preparing claim data based on resolved data:', claim);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['host'] = host;\n return claim;\n};\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER,\n TEXT = _ref.TEXT,\n DECIMAL = _ref.DECIMAL;\n\n var Claim = sequelize.define('Claim', {\n address: {\n type: STRING,\n default: null\n },\n amount: {\n type: DECIMAL(19, 8),\n default: null\n },\n claimId: {\n type: STRING,\n default: null\n },\n claimSequence: {\n type: INTEGER,\n default: null\n },\n decodedClaim: {\n type: BOOLEAN,\n default: null\n },\n depth: {\n type: INTEGER,\n default: null\n },\n effectiveAmount: {\n type: DECIMAL(19, 8),\n default: null\n },\n hasSignature: {\n type: BOOLEAN,\n default: null\n },\n height: {\n type: INTEGER,\n default: null\n },\n hex: {\n type: TEXT('long'),\n default: null\n },\n name: {\n type: STRING,\n default: null\n },\n nout: {\n type: INTEGER,\n default: null\n },\n txid: {\n type: STRING,\n default: null\n },\n validAtHeight: {\n type: INTEGER,\n default: null\n },\n outpoint: {\n type: STRING,\n default: null\n },\n claimType: {\n type: STRING,\n default: null\n },\n certificateId: {\n type: STRING,\n default: null\n },\n author: {\n type: STRING,\n default: null\n },\n description: {\n type: TEXT('long'),\n default: null\n },\n language: {\n type: STRING,\n default: null\n },\n license: {\n type: STRING,\n default: null\n },\n licenseUrl: {\n type: STRING,\n default: null\n },\n nsfw: {\n type: BOOLEAN,\n default: null\n },\n preview: {\n type: STRING,\n default: null\n },\n thumbnail: {\n type: STRING,\n default: null\n },\n title: {\n type: STRING,\n default: null\n },\n metadataVersion: {\n type: STRING,\n default: null\n },\n contentType: {\n type: STRING,\n default: null\n },\n source: {\n type: STRING,\n default: null\n },\n sourceType: {\n type: STRING,\n default: null\n },\n sourceVersion: {\n type: STRING,\n default: null\n },\n streamVersion: {\n type: STRING,\n default: null\n },\n valueVersion: {\n type: STRING,\n default: null\n },\n channelName: {\n type: STRING,\n allowNull: true,\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Claim.associate = function (db) {\n Claim.belongsTo(db.File, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {\n var _this = this;\n\n logger.debug('Claim.getShortClaimIdFromLongClaimId for ' + claimName + '#' + claimId);\n return new Promise(function (resolve, reject) {\n _this.findAll({\n where: { name: claimName },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n throw new Error('No claim(s) found with that claim name');\n default:\n resolve(returnShortId(result, claimId));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getAllChannelClaims = function (channelClaimId) {\n var _this2 = this;\n\n logger.debug('Claim.getAllChannelClaims for ' + channelClaimId);\n return new Promise(function (resolve, reject) {\n _this2.findAll({\n where: { certificateId: channelClaimId },\n order: [['height', 'ASC']],\n raw: true // returns an array of only data, not an array of instances\n }).then(function (channelClaimsArray) {\n // logger.debug('channelclaimsarray length:', channelClaimsArray.length);\n switch (channelClaimsArray.length) {\n case 0:\n return resolve(null);\n default:\n channelClaimsArray.forEach(function (claim) {\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n return claim;\n });\n return resolve(channelClaimsArray);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {\n var _this3 = this;\n\n logger.debug('finding claim id for claim ' + claimName + ' from channel ' + channelClaimId);\n return new Promise(function (resolve, reject) {\n _this3.findAll({\n where: { name: claimName, certificateId: channelClaimId },\n order: [['id', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(result[0].claimId);\n default:\n logger.error(result.length + ' records found for \"' + claimName + '\" in channel \"' + channelClaimId + '\"');\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {\n var _this4 = this;\n\n return new Promise(function (resolve, reject) {\n _this4.findAll({\n where: {\n name: name,\n claimId: {\n $like: shortId + '%'\n } },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n // note results must be sorted\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getTopFreeClaimIdByClaimName = function (name) {\n var _this5 = this;\n\n return new Promise(function (resolve, reject) {\n _this5.findAll({\n where: { name: name },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']] // note: maybe height and effective amount need to switch?\n }).then(function (result) {\n logger.debug('length of result', result.length);\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].dataValues.claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.validateLongClaimId = function (name, claimId) {\n var _this6 = this;\n\n return new Promise(function (resolve, reject) {\n _this6.findOne({\n where: { name: name, claimId: claimId }\n }).then(function (result) {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimId = function (claimName, claimId) {\n logger.debug('getLongClaimId(' + claimName + ', ' + claimId + ')');\n if (claimId && claimId.length === 40) {\n // if a full claim id is provided\n return this.validateLongClaimId(claimName, claimId);\n } else if (claimId && claimId.length < 40) {\n return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided\n } else {\n return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided\n }\n };\n\n Claim.resolveClaim = function (name, claimId) {\n var _this7 = this;\n\n logger.debug('Claim.resolveClaim: ' + name + ' ' + claimId);\n return new Promise(function (resolve, reject) {\n _this7.findAll({\n where: { name: name, claimId: claimId }\n }).then(function (claimArray) {\n switch (claimArray.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(prepareClaimData(claimArray[0].dataValues));\n default:\n logger.error('more than one record matches ' + name + '#' + claimId + ' in db.Claim');\n return resolve(prepareClaimData(claimArray[0].dataValues));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n return Claim;\n};\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER;\n\n var File = sequelize.define('File', {\n name: {\n type: STRING,\n allowNull: false\n },\n claimId: {\n type: STRING,\n allowNull: false\n },\n address: {\n type: STRING,\n allowNull: false\n },\n outpoint: {\n type: STRING,\n allowNull: false\n },\n height: {\n type: INTEGER,\n allowNull: false,\n default: 0\n },\n fileName: {\n type: STRING,\n allowNull: false\n },\n filePath: {\n type: STRING,\n allowNull: false\n },\n fileType: {\n type: STRING\n },\n nsfw: {\n type: BOOLEAN,\n allowNull: false,\n defaultValue: false\n },\n trendingEligible: {\n type: BOOLEAN,\n allowNull: false,\n defaultValue: true\n }\n }, {\n freezeTableName: true\n });\n\n File.associate = function (db) {\n File.hasMany(db.Request);\n File.hasOne(db.Claim);\n };\n\n File.getRecentClaims = function () {\n return this.findAll({\n where: { nsfw: false, trendingEligible: true },\n order: [['createdAt', 'DESC']],\n limit: 25\n });\n };\n\n return File;\n};\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n TEXT = _ref.TEXT;\n\n var Request = sequelize.define('Request', {\n action: {\n type: STRING,\n allowNull: false\n },\n url: {\n type: STRING,\n allowNull: false\n },\n ipAddress: {\n type: STRING,\n allowNull: true\n },\n result: {\n type: TEXT('long'),\n allowNull: true,\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Request.associate = function (db) {\n Request.belongsTo(db.File, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n return Request;\n};\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar bcrypt = __webpack_require__(20);\nvar logger = __webpack_require__(0);\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING;\n\n var User = sequelize.define('User', {\n userName: {\n type: STRING,\n allowNull: false\n },\n password: {\n type: STRING,\n allowNull: false\n }\n }, {\n freezeTableName: true\n });\n\n User.associate = function (db) {\n User.hasOne(db.Channel);\n };\n\n User.prototype.comparePassword = function (password) {\n return bcrypt.compare(password, this.password);\n };\n\n User.prototype.changePassword = function (newPassword) {\n var _this = this;\n\n return new Promise(function (resolve, reject) {\n // generate a salt string to use for hashing\n bcrypt.genSalt(function (saltError, salt) {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(newPassword, salt, function (hashError, hash) {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the current password with the new hash\n _this.update({ password: hash }).then(function () {\n resolve();\n }).catch(function (error) {\n reject(error);\n });\n });\n });\n });\n };\n\n // pre-save hook method to hash the user's password before the user's info is saved to the db.\n User.hook('beforeCreate', function (user, options) {\n logger.debug('User.beforeCreate hook...');\n return new Promise(function (resolve, reject) {\n // generate a salt string to use for hashing\n bcrypt.genSalt(function (saltError, salt) {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(user.password, salt, function (hashError, hash) {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the password string with the hash password value\n user.password = hash;\n resolve();\n });\n });\n });\n });\n\n return User;\n};\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"bcrypt\");\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar logger = __webpack_require__(0);\nvar db = __webpack_require__(2);\nvar lbryApi = __webpack_require__(6);\nvar publishHelpers = __webpack_require__(8);\n\nvar _require = __webpack_require__(1),\n _require$publishing = _require.publishing,\n primaryClaimAddress = _require$publishing.primaryClaimAddress,\n additionalClaimAddresses = _require$publishing.additionalClaimAddresses;\n\nvar Sequelize = __webpack_require__(3);\nvar Op = Sequelize.Op;\n\nmodule.exports = {\n publish: function publish(publishParams, fileName, fileType) {\n return new Promise(function (resolve, reject) {\n var publishResults = void 0,\n certificateId = void 0,\n channelName = void 0;\n // publish the file\n return lbryApi.publishClaim(publishParams).then(function (tx) {\n logger.info('Successfully published ' + publishParams.name + ' ' + fileName, tx);\n publishResults = tx;\n // get the channel information\n if (publishParams.channel_name) {\n logger.debug('this claim was published in channel: ' + publishParams.channel_name);\n return db.Channel.findOne({ where: { channelName: publishParams.channel_name } });\n } else {\n logger.debug('this claim was not published in a channel');\n return null;\n }\n }).then(function (channel) {\n // set channel information\n certificateId = null;\n channelName = null;\n if (channel) {\n certificateId = channel.channelClaimId;\n channelName = channel.channelName;\n }\n logger.debug('certificateId: ' + certificateId);\n }).then(function () {\n // create the File record\n var fileRecord = {\n name: publishParams.name,\n claimId: publishResults.claim_id,\n title: publishParams.metadata.title,\n description: publishParams.metadata.description,\n address: publishParams.claim_address,\n outpoint: publishResults.txid + ':' + publishResults.nout,\n height: 0,\n fileName: fileName,\n filePath: publishParams.file_path,\n fileType: fileType,\n nsfw: publishParams.metadata.nsfw\n };\n // create the Claim record\n var claimRecord = {\n name: publishParams.name,\n claimId: publishResults.claim_id,\n title: publishParams.metadata.title,\n description: publishParams.metadata.description,\n address: publishParams.claim_address,\n thumbnail: publishParams.metadata.thumbnail,\n outpoint: publishResults.txid + ':' + publishResults.nout,\n height: 0,\n contentType: fileType,\n nsfw: publishParams.metadata.nsfw,\n amount: publishParams.bid,\n certificateId: certificateId,\n channelName: channelName\n };\n // upsert criteria\n var upsertCriteria = {\n name: publishParams.name,\n claimId: publishResults.claim_id\n };\n // upsert the records\n return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n file = _ref2[0],\n claim = _ref2[1];\n\n logger.debug('File and Claim records successfully created');\n return Promise.all([file.setClaim(claim), claim.setFile(file)]);\n }).then(function () {\n logger.debug('File and Claim records successfully associated');\n resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;\n }).catch(function (error) {\n logger.error('PUBLISH ERROR', error);\n publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file\n reject(error);\n });\n });\n },\n claimNameIsAvailable: function claimNameIsAvailable(name) {\n var claimAddresses = additionalClaimAddresses || [];\n claimAddresses.push(primaryClaimAddress);\n // find any records where the name is used\n return db.Claim.findAll({\n attributes: ['address'],\n where: {\n name: name,\n address: _defineProperty({}, Op.or, claimAddresses)\n }\n }).then(function (result) {\n if (result.length >= 1) {\n throw new Error('That claim is already in use');\n };\n return name;\n }).catch(function (error) {\n throw error;\n });\n },\n checkChannelAvailability: function checkChannelAvailability(name) {\n return db.Channel.findAll({\n where: { channelName: name }\n }).then(function (result) {\n if (result.length >= 1) {\n throw new Error('That channel has already been claimed');\n }\n return name;\n }).catch(function (error) {\n throw error;\n });\n }\n};\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"axios\");\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar lbryConfig = {\n api: {\n apiHost: 'localhost',\n apiPort: '5279'\n }\n};\n\nmodule.exports = lbryConfig;\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"universal-analytics\");\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"fs\");\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar logger = __webpack_require__(0);\n\nmodule.exports = {\n handleErrorResponse: function handleErrorResponse(originalUrl, ip, error, res) {\n logger.error('Error on ' + originalUrl, module.exports.useObjectPropertiesIfNoKeys(error));\n\n var _module$exports$retur = module.exports.returnErrorMessageAndStatus(error),\n _module$exports$retur2 = _slicedToArray(_module$exports$retur, 2),\n status = _module$exports$retur2[0],\n message = _module$exports$retur2[1];\n\n res.status(status).json(module.exports.createErrorResponsePayload(status, message));\n },\n returnErrorMessageAndStatus: function returnErrorMessageAndStatus(error) {\n var status = void 0,\n message = void 0;\n // check for daemon being turned off\n if (error.code === 'ECONNREFUSED') {\n status = 503;\n message = 'Connection refused. The daemon may not be running.';\n // fallback for everything else\n } else {\n status = 400;\n if (error.message) {\n message = error.message;\n } else {\n message = error;\n };\n };\n return [status, message];\n },\n useObjectPropertiesIfNoKeys: function useObjectPropertiesIfNoKeys(err) {\n if (Object.keys(err).length === 0) {\n var newErrorObject = {};\n Object.getOwnPropertyNames(err).forEach(function (key) {\n newErrorObject[key] = err[key];\n });\n return newErrorObject;\n }\n return err;\n },\n createErrorResponsePayload: function createErrorResponsePayload(status, message) {\n return {\n status: status,\n success: false,\n message: message\n };\n }\n};\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar db = __webpack_require__(2);\nvar logger = __webpack_require__(0);\n\nmodule.exports = {\n authenticateUser: function authenticateUser(channelName, channelId, channelPassword, user) {\n // case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided\n if (!channelName && !channelId) {\n return {\n channelName: null,\n channelClaimId: null\n };\n }\n // case: channelName or channel Id are provided with user token\n if (user) {\n if (channelName && channelName !== user.channelName) {\n throw new Error('the provided channel name does not match user credentials');\n }\n if (channelId && channelId !== user.channelClaimId) {\n throw new Error('the provided channel id does not match user credentials');\n }\n return {\n channelName: user.channelName,\n channelClaimId: user.channelClaimId\n };\n }\n // case: channelName or channel Id are provided with password instead of user token\n if (!channelPassword) throw new Error('no channel password provided');\n return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);\n },\n authenticateChannelCredentials: function authenticateChannelCredentials(channelName, channelId, userPassword) {\n return new Promise(function (resolve, reject) {\n // hoisted variables\n var channelData = void 0;\n // build the params for finding the channel\n var channelFindParams = {};\n if (channelName) channelFindParams['channelName'] = channelName;\n if (channelId) channelFindParams['channelClaimId'] = channelId;\n // find the channel\n db.Channel.findOne({\n where: channelFindParams\n }).then(function (channel) {\n if (!channel) {\n logger.debug('no channel found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n channelData = channel.get();\n logger.debug('channel data:', channelData);\n return db.User.findOne({\n where: { userName: channelData.channelName.substring(1) }\n });\n }).then(function (user) {\n if (!user) {\n logger.debug('no user found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n return user.comparePassword(userPassword);\n }).then(function (isMatch) {\n if (!isMatch) {\n logger.debug('incorrect password');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n logger.debug('...password was a match...');\n resolve(channelData);\n }).catch(function (error) {\n reject(error);\n });\n });\n }\n};\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar db = __webpack_require__(2);\nvar logger = __webpack_require__(0);\n\nvar _require = __webpack_require__(29),\n returnPaginatedChannelClaims = _require.returnPaginatedChannelClaims;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\nvar NO_FILE = 'NO_FILE';\n\nmodule.exports = {\n getClaimId: function getClaimId(channelName, channelClaimId, name, claimId) {\n if (channelName) {\n return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);\n } else {\n return module.exports.getClaimIdByClaim(name, claimId);\n }\n },\n getClaimIdByClaim: function getClaimIdByClaim(claimName, claimId) {\n logger.debug('getClaimIdByClaim(' + claimName + ', ' + claimId + ')');\n return new Promise(function (resolve, reject) {\n db.Claim.getLongClaimId(claimName, claimId).then(function (longClaimId) {\n if (!longClaimId) {\n resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaimIdByChannel: function getClaimIdByChannel(channelName, channelClaimId, claimName) {\n logger.debug('getClaimIdByChannel(' + channelName + ', ' + channelClaimId + ', ' + claimName + ')');\n return new Promise(function (resolve, reject) {\n db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id\n .then(function (longChannelId) {\n if (!longChannelId) {\n return [null, null];\n }\n return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n longChannelId = _ref2[0],\n longClaimId = _ref2[1];\n\n if (!longChannelId) {\n return resolve(NO_CHANNEL);\n }\n if (!longClaimId) {\n return resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getChannelData: function getChannelData(channelName, channelClaimId, page) {\n return new Promise(function (resolve, reject) {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);\n }).then(function (_ref3) {\n var _ref4 = _slicedToArray(_ref3, 2),\n longChannelClaimId = _ref4[0],\n shortChannelClaimId = _ref4[1];\n\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. return all the channel information\n resolve({\n channelName: channelName,\n longChannelClaimId: longChannelClaimId,\n shortChannelClaimId: shortChannelClaimId\n });\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getChannelClaims: function getChannelClaims(channelName, channelClaimId, page) {\n return new Promise(function (resolve, reject) {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);\n }).then(function (_ref5) {\n var _ref6 = _slicedToArray(_ref5, 2),\n longChannelClaimId = _ref6[0],\n channelClaimsArray = _ref6[1];\n\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. format the data for the view, including pagination\n var paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);\n // 4. return all the channel information and contents\n resolve(paginatedChannelViewData);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getLocalFileRecord: function getLocalFileRecord(claimId, name) {\n return db.File.findOne({ where: { claimId: claimId, name: name } }).then(function (file) {\n if (!file) {\n return NO_FILE;\n }\n return file.dataValues;\n });\n }\n};\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar CLAIMS_PER_PAGE = 12;\n\nmodule.exports = {\n returnPaginatedChannelClaims: function returnPaginatedChannelClaims(channelName, longChannelClaimId, claims, page) {\n var totalPages = module.exports.determineTotalPages(claims);\n var paginationPage = module.exports.getPageFromQuery(page);\n var viewData = {\n channelName: channelName,\n longChannelClaimId: longChannelClaimId,\n claims: module.exports.extractPageFromClaims(claims, paginationPage),\n previousPage: module.exports.determinePreviousPage(paginationPage),\n currentPage: paginationPage,\n nextPage: module.exports.determineNextPage(totalPages, paginationPage),\n totalPages: totalPages,\n totalResults: module.exports.determineTotalClaims(claims)\n };\n return viewData;\n },\n getPageFromQuery: function getPageFromQuery(page) {\n if (page) {\n return parseInt(page);\n }\n return 1;\n },\n extractPageFromClaims: function extractPageFromClaims(claims, pageNumber) {\n if (!claims) {\n return []; // if no claims, return this default\n }\n // logger.debug('claims is array?', Array.isArray(claims));\n // logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));\n var claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;\n var claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;\n var pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);\n return pageOfClaims;\n },\n determineTotalPages: function determineTotalPages(claims) {\n if (!claims) {\n return 0;\n } else {\n var totalClaims = claims.length;\n if (totalClaims < CLAIMS_PER_PAGE) {\n return 1;\n }\n var fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);\n var remainder = totalClaims % CLAIMS_PER_PAGE;\n if (remainder === 0) {\n return fullPages;\n }\n return fullPages + 1;\n }\n },\n determinePreviousPage: function determinePreviousPage(currentPage) {\n if (currentPage === 1) {\n return null;\n }\n return currentPage - 1;\n },\n determineNextPage: function determineNextPage(totalPages, currentPage) {\n if (currentPage === totalPages) {\n return null;\n }\n return currentPage + 1;\n },\n determineTotalClaims: function determineTotalClaims(claims) {\n if (!claims) {\n return 0;\n }\n return claims.length;\n }\n};\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(0);\n\nfunction LoggerConfig() {\n var _this = this;\n\n this.logLevel = 'debug';\n this.configure = function (config) {\n if (!config) {\n return console.log('No logger config received.');\n }\n // update values with local config params\n var logLevel = config.logLevel;\n\n _this.logLevel = logLevel;\n // configure the winston logger\n logger.configure({\n transports: [new logger.transports.Console({\n level: _this.logLevel,\n timestamp: false,\n colorize: true,\n prettyPrint: true,\n handleExceptions: true,\n humanReadableUnhandledException: true\n })]\n });\n // test all the log levels\n logger.error('Level 0');\n logger.warn('Level 1');\n logger.info('Level 2');\n logger.verbose('Level 3');\n logger.debug('Level 4');\n logger.silly('Level 5');\n };\n};\n\nmodule.exports = new LoggerConfig();\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar winstonSlackWebHook = __webpack_require__(32).SlackWebHook;\nvar winston = __webpack_require__(0);\n\nfunction SlackConfig() {\n var _this = this;\n\n this.slackWebHook = 'default';\n this.slackErrorChannel = 'default';\n this.slackInfoChannel = 'default';\n this.configure = function (config) {\n if (!config) {\n return console.log('No slack config received.');\n }\n // update variables\n var slackWebHook = config.slackWebHook,\n slackErrorChannel = config.slackErrorChannel,\n slackInfoChannel = config.slackInfoChannel;\n\n _this.slackWebHook = slackWebHook;\n _this.slackErrorChannel = slackErrorChannel;\n _this.slackInfoChannel = slackInfoChannel;\n // update slack webhook settings\n if (_this.slackWebHook) {\n // add a transport for errors to slack\n if (_this.slackErrorChannel) {\n winston.add(winstonSlackWebHook, {\n name: 'slack-errors-transport',\n level: 'warn',\n webhookUrl: _this.slackWebHook,\n channel: _this.slackErrorChannel,\n username: 'spee.ch',\n iconEmoji: ':face_with_head_bandage:'\n });\n };\n if (slackInfoChannel) {\n winston.add(winstonSlackWebHook, {\n name: 'slack-info-transport',\n level: 'info',\n webhookUrl: _this.slackWebHook,\n channel: _this.slackInfoChannel,\n username: 'spee.ch',\n iconEmoji: ':nerd_face:'\n });\n };\n // send test messages\n winston.error('Slack \"error\" logging is online.');\n winston.info('Slack \"info\" logging is online.');\n } else {\n winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');\n }\n };\n};\n\nmodule.exports = new SlackConfig();\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"winston-slack-webhook\");\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// index.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 9);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 83cd2a562153e7e829c5","module.exports = require(\"winston\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"winston\"\n// module id = 0\n// module chunks = 0","function SiteConfig () {\n this.analytics = {\n googleId: 'default',\n };\n this.assetDefaults = {\n description: 'An asset published on Spee.ch',\n thumbnail : 'https://spee.ch/assets/img/video_thumb_default.png',\n title : 'Spee.ch',\n };\n this.auth = {\n sessionKey: 'default',\n };\n this.customComponents = {\n components: {},\n containers: {},\n pages : {},\n };\n this.details = {\n description: 'Open-source, decentralized image and video sharing.',\n host : 'default',\n port : 3000,\n title : 'Spee.ch',\n twitter : '@spee_ch',\n };\n this.publishing = {\n additionalClaimAddresses: [],\n disabled : false,\n disabledMessage : 'Please check back soon.',\n primaryClaimAddress : 'default',\n thumbnailChannel : 'default',\n thumbnailChannelId : 'default',\n uploadDirectory : '/home/lbry/Uploads',\n };\n this.configure = (config) => {\n if (!config) {\n return console.log('No site config received.');\n }\n const { analytics, assetDefaults, auth, customComponents, details, publishing } = config;\n this.analytics = analytics;\n this.assetDefaults = assetDefaults;\n this.auth = auth;\n this.details = details;\n this.publishing = publishing;\n this.customComponents = customComponents;\n };\n};\n\nmodule.exports = new SiteConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/siteConfig.js","const Sequelize = require('sequelize');\nconst logger = require('winston');\n\nlogger.info('exporting sequelize models');\nconst { database, username, password } = require('../../config/mysqlConfig');\n\nconst db = {};\n// set sequelize options\nconst sequelize = new Sequelize(database, username, password, {\n host : 'localhost',\n dialect : 'mysql',\n dialectOptions: {decimalNumbers: true}, // fix to ensure DECIMAL will not be stored as a string\n logging : false,\n pool : {\n max : 5,\n min : 0,\n idle : 10000,\n acquire: 10000,\n },\n});\n\n// establish mysql connection\nsequelize\n .authenticate()\n .then(() => {\n logger.info('Sequelize has established mysql connection successfully.');\n })\n .catch(err => {\n logger.error('Sequelize was unable to connect to the database:', err);\n });\n\n// manually add each model to the db object\nconst Certificate = require('./certificate.js');\nconst Channel = require('./channel.js');\nconst Claim = require('./claim.js');\nconst File = require('./file.js');\nconst Request = require('./request.js');\nconst User = require('./user.js');\ndb['Certificate'] = sequelize.import('Certificate', Certificate);\ndb['Channel'] = sequelize.import('Channel', Channel);\ndb['Claim'] = sequelize.import('Claim', Claim);\ndb['File'] = sequelize.import('File', File);\ndb['Request'] = sequelize.import('Request', Request);\ndb['User'] = sequelize.import('User', User);\n\n// run model.association for each model in the db object that has an association\nObject.keys(db).forEach(modelName => {\n if (db[modelName].associate) {\n logger.info('Associating model:', modelName);\n db[modelName].associate(db);\n }\n});\n\ndb.sequelize = sequelize;\ndb.Sequelize = Sequelize;\n\n// add an 'upsert' method to the db object\ndb.upsert = (Model, values, condition, tableName) => {\n return Model\n .findOne({\n where: condition,\n })\n .then(obj => {\n if (obj) { // update\n logger.debug(`updating record in db.${tableName}`);\n return obj.update(values);\n } else { // insert\n logger.debug(`creating record in db.${tableName}`);\n return Model.create(values);\n }\n })\n .catch(function (error) {\n logger.error(`${tableName}.upsert error`, error);\n throw error;\n });\n};\n\nmodule.exports = db;\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/index.js","module.exports = require(\"sequelize\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"sequelize\"\n// module id = 3\n// module chunks = 0","function mysql () {\n this.database = 'default';\n this.username = 'default';\n this.password = 'default';\n this.configure = (config) => {\n if (!config) {\n return console.log('No MySQL config received.');\n }\n const {database, username, password} = config;\n this.database = database;\n this.username = username;\n this.password = password;\n };\n};\n\nmodule.exports = new mysql();\n\n\n\n// WEBPACK FOOTER //\n// ./config/mysqlConfig.js","module.exports = {\n returnShortId: function (claimsArray, longId) {\n let claimIndex;\n let shortId = longId.substring(0, 1); // default short id is the first letter\n let shortIdLength = 0;\n // find the index of this claim id\n claimIndex = claimsArray.findIndex(element => {\n return element.claimId === longId;\n });\n if (claimIndex < 0) {\n throw new Error('claim id not found in claims list');\n }\n // get an array of all claims with lower height\n let possibleMatches = claimsArray.slice(0, claimIndex);\n // remove certificates with the same prefixes until none are left.\n while (possibleMatches.length > 0) {\n shortIdLength += 1;\n shortId = longId.substring(0, shortIdLength);\n possibleMatches = possibleMatches.filter(element => {\n return (element.claimId && (element.claimId.substring(0, shortIdLength) === shortId));\n });\n }\n return shortId;\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/sequelizeHelpers.js","const axios = require('axios');\nconst logger = require('winston');\nconst { api: { apiHost, apiPort } } = require('../../config/lbryConfig.js');\nconst lbryApiUri = 'http://' + apiHost + ':' + apiPort;\nconst { chooseGaLbrynetPublishLabel, sendGATimingEvent } = require('./googleAnalytics.js');\n\nconst handleLbrynetResponse = ({ data }, resolve, reject) => {\n logger.debug('lbry api data:', data);\n if (data.result) {\n // check for an error\n if (data.result.error) {\n logger.debug('Lbrynet api error:', data.result.error);\n reject(new Error(data.result.error));\n return;\n };\n resolve(data.result);\n return;\n }\n // fallback in case it just timed out\n reject(JSON.stringify(data));\n};\n\nmodule.exports = {\n publishClaim (publishParams) {\n logger.debug(`lbryApi >> Publishing claim to \"${publishParams.name}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'publish',\n params: publishParams,\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaim (uri) {\n logger.debug(`lbryApi >> Getting Claim for \"${uri}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'get',\n params: { uri, timeout: 20 },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaimList (claimName) {\n logger.debug(`lbryApi >> Getting claim_list for \"${claimName}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'claim_list',\n params: { name: claimName },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n resolveUri (uri) {\n logger.debug(`lbryApi >> Resolving URI for \"${uri}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'resolve',\n params: { uri },\n })\n .then(({ data }) => {\n sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());\n if (data.result[uri].error) { // check for errors\n reject(data.result[uri].error);\n } else { // if no errors, resolve\n resolve(data.result[uri]);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getDownloadDirectory () {\n logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'settings_get',\n })\n .then(({ data }) => {\n sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());\n if (data.result) {\n resolve(data.result.download_directory);\n } else {\n return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');\n }\n })\n .catch(error => {\n logger.error('Lbrynet Error:', error);\n resolve('/home/lbry/Downloads/');\n });\n });\n },\n createChannel (name) {\n logger.debug(`lbryApi >> Creating channel for ${name}...`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'channel_new',\n params: {\n channel_name: name,\n amount : 0.1,\n },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/lbryApi.js","const logger = require('winston');\nconst ua = require('universal-analytics');\nconst { analytics : { googleId }, details: { title } } = require('../../config/siteConfig.js');\n\nfunction createServeEventParams (headers, ip, originalUrl) {\n return {\n eventCategory : 'client requests',\n eventAction : 'serve request',\n eventLabel : originalUrl,\n ipOverride : ip,\n userAgentOverride: headers['user-agent'],\n };\n};\n\nfunction createPublishTimingEventParams (category, variable, label, startTime, endTime) {\n const duration = endTime - startTime;\n return {\n userTimingCategory : category,\n userTimingVariableName: variable,\n userTimingTime : duration,\n userTimingLabel : label,\n };\n};\n\nfunction sendGoogleAnalyticsEvent (ip, params) {\n const visitorId = ip.replace(/\\./g, '-');\n const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.event(params, (err) => {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n });\n};\n\nfunction sendGoogleAnalyticsTiming (visitorId, params) {\n const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.timing(params, (err) => {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n logger.debug(`Timing event successfully sent to google analytics`);\n });\n};\n\nmodule.exports = {\n sendGAServeEvent (headers, ip, originalUrl) {\n const params = createServeEventParams(headers, ip, originalUrl);\n sendGoogleAnalyticsEvent(ip, params);\n },\n sendGATimingEvent (category, variable, label, startTime, endTime) {\n const params = createPublishTimingEventParams(category, variable, label, startTime, endTime);\n sendGoogleAnalyticsTiming(title, params);\n },\n chooseGaLbrynetPublishLabel ({ channel_name: channelName, channel_id: channelId }) {\n return (channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM');\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/googleAnalytics.js","const logger = require('winston');\nconst fs = require('fs');\n\nconst { details, publishing } = require('../../config/siteConfig.js');\n\nmodule.exports = {\n parsePublishApiRequestBody ({name, nsfw, license, title, description, thumbnail}) {\n // validate name\n if (!name) {\n throw new Error('no name field found in request');\n }\n const invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);\n if (invalidNameCharacters) {\n throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and \"-\"');\n }\n // optional parameters\n nsfw = (nsfw === 'true');\n license = license || null;\n title = title || null;\n description = description || null;\n thumbnail = thumbnail || null;\n // return results\n return {\n name,\n nsfw,\n license,\n title,\n description,\n thumbnail,\n };\n },\n parsePublishApiRequestFiles ({file, thumbnail}) {\n // make sure a file was provided\n if (!file) {\n throw new Error('no file with key of [file] found in request');\n }\n if (!file.path) {\n throw new Error('no file path found');\n }\n if (!file.type) {\n throw new Error('no file type found');\n }\n if (!file.size) {\n throw new Error('no file type found');\n }\n // validate the file name\n if (/'/.test(file.name)) {\n throw new Error('apostrophes are not allowed in the file name');\n }\n // validate the file\n module.exports.validateFileTypeAndSize(file);\n // return results\n return {\n fileName : file.name,\n filePath : file.path,\n fileType : file.type,\n thumbnailFileName: (thumbnail ? thumbnail.name : null),\n thumbnailFilePath: (thumbnail ? thumbnail.path : null),\n thumbnailFileType: (thumbnail ? thumbnail.type : null),\n };\n },\n validateFileTypeAndSize (file) {\n // check file type and size\n switch (file.type) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n if (file.size > 10000000) {\n logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .gif was too big');\n throw new Error('Sorry, .gifs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .mp4 was too big');\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n logger.debug('publish > file validation > unrecognized file type');\n throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n return file;\n },\n createBasicPublishParams (filePath, name, title, description, license, nsfw, thumbnail) {\n logger.debug(`Creating Publish Parameters`);\n // provide defaults for title\n if (title === null || title.trim() === '') {\n title = name;\n }\n // provide default for description\n if (description === null || description.trim() === '') {\n description = '';\n }\n // provide default for license\n if (license === null || license.trim() === '') {\n license = ' '; // default to empty string\n }\n // create the publish params\n const publishParams = {\n name,\n file_path: filePath,\n bid : 0.01,\n metadata : {\n description,\n title,\n author : details.title,\n language: 'en',\n license,\n nsfw,\n },\n claim_address: publishing.primaryClaimAddress,\n };\n // add thumbnail to channel if video\n if (thumbnail) {\n publishParams['metadata']['thumbnail'] = thumbnail;\n }\n return publishParams;\n },\n createThumbnailPublishParams (thumbnailFilePath, claimName, license, nsfw) {\n if (!thumbnailFilePath) {\n return;\n }\n logger.debug(`Creating Thumbnail Publish Parameters`);\n // create the publish params\n return {\n name : `${claimName}-thumb`,\n file_path: thumbnailFilePath,\n bid : 0.01,\n metadata : {\n title : `${claimName} thumbnail`,\n description: `a thumbnail for ${claimName}`,\n author : details.title,\n language : 'en',\n license,\n nsfw,\n },\n claim_address: publishing.primaryClaimAddress,\n channel_name : publishing.thumbnailChannel,\n channel_id : publishing.thumbnailChannelId,\n };\n },\n deleteTemporaryFile (filePath) {\n fs.unlink(filePath, err => {\n if (err) {\n logger.error(`error deleting temporary file ${filePath}`);\n throw err;\n }\n logger.debug(`successfully deleted ${filePath}`);\n });\n },\n addGetResultsToFileData (fileInfo, getResult) {\n fileInfo.fileName = getResult.file_name;\n fileInfo.filePath = getResult.download_path;\n return fileInfo;\n },\n createFileData ({ name, claimId, outpoint, height, address, nsfw, contentType }) {\n return {\n name,\n claimId,\n outpoint,\n height,\n address,\n fileName: '',\n filePath: '',\n fileType: contentType,\n nsfw,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/publishHelpers.js","module.exports = require(\"babel-polyfill\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"babel-polyfill\"\n// module id = 10\n// module chunks = 0","module.exports = require(\"whatwg-fetch\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"whatwg-fetch\"\n// module id = 11\n// module chunks = 0","// const Server = require('./server/server.js');\n// const Components = require('./client/components');\n// const Containers = require('./client/containers');\n// const Pages = require('./client/pages');\nconst apiRoutes = require('./server/routes/apiRoutes.js');\nconst logger = require('./config/loggerConfig.js');\nconst mysql = require('./config/mysqlConfig.js');\nconst slack = require('./config/slackConfig.js');\nconst database = require('./server/models');\nconst localLoginStrategy = require('./passport/local-login.js');\nconst localSignupStrategy = require('./passport/local-signup.js');\n\nconst exports = {\n // Server,\n // Components,\n // Containers,\n // Pages,\n apiRoutes,\n config: {\n logger,\n mysql,\n slack,\n },\n database,\n passport: {\n localLoginStrategy,\n localSignupStrategy,\n },\n};\n\nmodule.exports = exports;\n\n\n\n// WEBPACK FOOTER //\n// ./speech.js","const logger = require('winston');\nconst { details: { host } } = require('../../config/siteConfig.js');\nconst db = require('../models');\nconst { claimNameIsAvailable, checkChannelAvailability, publish } = require('../controllers/publishController.js');\nconst { getClaimList, resolveUri, getClaim } = require('../helpers/lbryApi.js');\nconst { addGetResultsToFileData, createBasicPublishParams, createThumbnailPublishParams, parsePublishApiRequestBody, parsePublishApiRequestFiles, createFileData } = require('../helpers/publishHelpers.js');\nconst errorHandlers = require('../helpers/errorHandlers.js');\nconst { sendGATimingEvent } = require('../helpers/googleAnalytics.js');\nconst { authenticateUser } = require('../auth/authentication.js');\nconst { getChannelData, getChannelClaims, getClaimId } = require('../controllers/serveController.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\n\nmodule.exports = {\n // route to check whether site has published to a channel\n channelAvailabilityRoute ({ ip, originalUrl, params: { name } }, res) {\n const gaStartTime = Date.now();\n checkChannelAvailability(name)\n .then(availableName => {\n res.status(200).json(availableName);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to get a short channel id from long channel Id\n channelShortIdRoute ({ ip, originalUrl, params }, res) {\n db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name)\n .then(shortId => {\n res.status(200).json(shortId);\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n channelDataRoute ({ ip, originalUrl, body, params }, res) {\n const channelName = params.channelName;\n let channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n getChannelData(channelName, channelClaimId, 0)\n .then(data => {\n if (data === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel was found'});\n }\n res.status(200).json({success: true, data});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n channelClaimsRoute ({ ip, originalUrl, body, params }, res) {\n const channelName = params.channelName;\n let channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n const page = params.page;\n getChannelClaims(channelName, channelClaimId, page)\n .then(data => {\n if (data === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel was found'});\n }\n res.status(200).json({success: true, data});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to run a claim_list request on the daemon\n claimListRoute ({ ip, originalUrl, params }, res) {\n getClaimList(params.name)\n .then(claimsList => {\n res.status(200).json(claimsList);\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to get an asset\n claimGetRoute ({ ip, originalUrl, params }, res) {\n const name = params.name;\n const claimId = params.claimId;\n // resolve the claim\n db.Claim.resolveClaim(name, claimId)\n .then(resolveResult => {\n // make sure a claim actually exists at that uri\n if (!resolveResult) {\n throw new Error('No matching uri found in Claim table');\n }\n let fileData = createFileData(resolveResult);\n // get the claim\n return Promise.all([fileData, getClaim(`${name}#${claimId}`)]);\n })\n .then(([ fileData, getResult ]) => {\n fileData = addGetResultsToFileData(fileData, getResult);\n return Promise.all([db.upsert(db.File, fileData, {name, claimId}, 'File'), getResult]);\n })\n .then(([ fileRecord, {message, completed} ]) => {\n res.status(200).json({ success: true, message, completed });\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to check whether this site published to a claim\n claimAvailabilityRoute ({ ip, originalUrl, params: { name } }, res) {\n const gaStartTime = Date.now();\n claimNameIsAvailable(name)\n .then(result => {\n res.status(200).json(result);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to run a resolve request on the daemon\n claimResolveRoute ({ headers, ip, originalUrl, params }, res) {\n resolveUri(`${params.name}#${params.claimId}`)\n .then(resolvedUri => {\n res.status(200).json(resolvedUri);\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to run a publish request on the daemon\n claimPublishRoute ({ body, files, headers, ip, originalUrl, user }, res) {\n // define variables\n let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title;\n // record the start time of the request\n gaStartTime = Date.now();\n // validate the body and files of the request\n try {\n // validateApiPublishRequest(body, files);\n ({name, nsfw, license, title, description, thumbnail} = parsePublishApiRequestBody(body));\n ({fileName, filePath, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType} = parsePublishApiRequestFiles(files));\n ({channelName, channelId, channelPassword} = body);\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n // check channel authorization\n Promise.all([\n authenticateUser(channelName, channelId, channelPassword, user),\n claimNameIsAvailable(name),\n createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail),\n createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw),\n ])\n .then(([{channelName, channelClaimId}, validatedClaimName, publishParams, thumbnailPublishParams]) => {\n // add channel details to the publish params\n if (channelName && channelClaimId) {\n publishParams['channel_name'] = channelName;\n publishParams['channel_id'] = channelClaimId;\n }\n // publish the thumbnail\n if (thumbnailPublishParams) {\n publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);\n }\n // publish the asset\n return publish(publishParams, fileName, fileType);\n })\n .then(result => {\n res.status(200).json({\n success: true,\n message: 'publish completed successfully',\n data : {\n name,\n claimId: result.claim_id,\n url : `${host}/${result.claim_id}/${name}`,\n lbryTx : result,\n },\n });\n // record the publish end time and send to google analytics\n sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to get a short claim id from long claim Id\n claimShortIdRoute ({ ip, originalUrl, body, params }, res) {\n db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name)\n .then(shortId => {\n res.status(200).json({success: true, data: shortId});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n claimLongIdRoute ({ ip, originalUrl, body, params }, res) {\n logger.debug('body:', body);\n const channelName = body.channelName;\n const channelClaimId = body.channelClaimId;\n const claimName = body.claimName;\n const claimId = body.claimId;\n getClaimId(channelName, channelClaimId, claimName, claimId)\n .then(result => {\n if (result === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel could be found'});\n }\n if (result === NO_CLAIM) {\n return res.status(404).json({success: false, message: 'No matching claim id could be found'});\n }\n res.status(200).json({success: true, data: result});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n claimDataRoute ({ ip, originalUrl, body, params }, res) {\n const claimName = params.claimName;\n let claimId = params.claimId;\n if (claimId === 'none') claimId = null;\n db.Claim.resolveClaim(claimName, claimId)\n .then(claimInfo => {\n if (!claimInfo) {\n return res.status(404).json({success: false, message: 'No claim could be found'});\n }\n res.status(200).json({success: true, data: claimInfo});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n // route to see if asset is available locally\n fileAvailabilityRoute ({ ip, originalUrl, params }, res) {\n const name = params.name;\n const claimId = params.claimId;\n db.File.findOne({where: {name, claimId}})\n .then(result => {\n if (result) {\n return res.status(200).json({success: true, data: true});\n }\n res.status(200).json({success: true, data: false});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/apiRoutes.js","const logger = require('winston');\nconst { returnShortId } = require('../helpers/sequelizeHelpers.js');\n\nmodule.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {\n const Certificate = sequelize.define(\n 'Certificate',\n {\n address: {\n type : STRING,\n default: null,\n },\n amount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n claimId: {\n type : STRING,\n default: null,\n },\n claimSequence: {\n type : INTEGER,\n default: null,\n },\n decodedClaim: {\n type : BOOLEAN,\n default: null,\n },\n depth: {\n type : INTEGER,\n default: null,\n },\n effectiveAmount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n hasSignature: {\n type : BOOLEAN,\n default: null,\n },\n height: {\n type : INTEGER,\n default: null,\n },\n hex: {\n type : TEXT('long'),\n default: null,\n },\n name: {\n type : STRING,\n default: null,\n },\n nout: {\n type : INTEGER,\n default: null,\n },\n txid: {\n type : STRING,\n default: null,\n },\n validAtHeight: {\n type : INTEGER,\n default: null,\n },\n outpoint: {\n type : STRING,\n default: null,\n },\n valueVersion: {\n type : STRING,\n default: null,\n },\n claimType: {\n type : STRING,\n default: null,\n },\n certificateVersion: {\n type : STRING,\n default: null,\n },\n keyType: {\n type : STRING,\n default: null,\n },\n publicKey: {\n type : TEXT('long'),\n default: null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Certificate.associate = db => {\n Certificate.belongsTo(db.Channel, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {\n logger.debug(`getShortChannelIdFromLongChannelId ${channelName}:${longChannelId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {name: channelName},\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n throw new Error('No channel(s) found with that channel name');\n default:\n return resolve(returnShortId(result, longChannelId));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {\n logger.debug(`getLongChannelIdFromShortChannelId(${channelName}, ${channelClaimId})`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {\n name : channelName,\n claimId: {\n $like: `${channelClaimId}%`,\n },\n },\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default: // note results must be sorted\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromChannelName = function (channelName) {\n logger.debug(`getLongChannelIdFromChannelName(${channelName})`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: channelName },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.validateLongChannelId = function (name, claimId) {\n logger.debug(`validateLongChannelId(${name}, ${claimId})`);\n return new Promise((resolve, reject) => {\n this.findOne({\n where: {name, claimId},\n })\n .then(result => {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelId = function (channelName, channelClaimId) {\n logger.debug(`getLongChannelId(${channelName}, ${channelClaimId})`);\n if (channelClaimId && (channelClaimId.length === 40)) { // if a full channel id is provided\n return this.validateLongChannelId(channelName, channelClaimId);\n } else if (channelClaimId && channelClaimId.length < 40) { // if a short channel id is provided\n return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);\n } else {\n return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided\n }\n };\n\n return Certificate;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/certificate.js","module.exports = (sequelize, { STRING }) => {\n const Channel = sequelize.define(\n 'Channel',\n {\n channelName: {\n type : STRING,\n allowNull: false,\n },\n channelClaimId: {\n type : STRING,\n allowNull: false,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Channel.associate = db => {\n Channel.belongsTo(db.User);\n Channel.hasOne(db.Certificate);\n };\n\n return Channel;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/channel.js","const logger = require('winston');\nconst { returnShortId } = require('../helpers/sequelizeHelpers.js');\nconst { assetDefaults: { thumbnail: defaultThumbnail }, details: { host } } = require('../../config/siteConfig.js');\n\nfunction determineFileExtensionFromContentType (contentType) {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n return 'jpeg';\n case 'image/png':\n return 'png';\n case 'image/gif':\n return 'gif';\n case 'video/mp4':\n return 'mp4';\n default:\n logger.debug('setting unknown file type as file extension jpeg');\n return 'jpeg';\n }\n};\n\nfunction determineThumbnail (storedThumbnail, defaultThumbnail) {\n if (storedThumbnail === '') {\n return defaultThumbnail;\n }\n return storedThumbnail;\n};\n\nfunction prepareClaimData (claim) {\n // logger.debug('preparing claim data based on resolved data:', claim);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['host'] = host;\n return claim;\n};\n\nmodule.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {\n const Claim = sequelize.define(\n 'Claim',\n {\n address: {\n type : STRING,\n default: null,\n },\n amount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n claimId: {\n type : STRING,\n default: null,\n },\n claimSequence: {\n type : INTEGER,\n default: null,\n },\n decodedClaim: {\n type : BOOLEAN,\n default: null,\n },\n depth: {\n type : INTEGER,\n default: null,\n },\n effectiveAmount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n hasSignature: {\n type : BOOLEAN,\n default: null,\n },\n height: {\n type : INTEGER,\n default: null,\n },\n hex: {\n type : TEXT('long'),\n default: null,\n },\n name: {\n type : STRING,\n default: null,\n },\n nout: {\n type : INTEGER,\n default: null,\n },\n txid: {\n type : STRING,\n default: null,\n },\n validAtHeight: {\n type : INTEGER,\n default: null,\n },\n outpoint: {\n type : STRING,\n default: null,\n },\n claimType: {\n type : STRING,\n default: null,\n },\n certificateId: {\n type : STRING,\n default: null,\n },\n author: {\n type : STRING,\n default: null,\n },\n description: {\n type : TEXT('long'),\n default: null,\n },\n language: {\n type : STRING,\n default: null,\n },\n license: {\n type : STRING,\n default: null,\n },\n licenseUrl: {\n type : STRING,\n default: null,\n },\n nsfw: {\n type : BOOLEAN,\n default: null,\n },\n preview: {\n type : STRING,\n default: null,\n },\n thumbnail: {\n type : STRING,\n default: null,\n },\n title: {\n type : STRING,\n default: null,\n },\n metadataVersion: {\n type : STRING,\n default: null,\n },\n contentType: {\n type : STRING,\n default: null,\n },\n source: {\n type : STRING,\n default: null,\n },\n sourceType: {\n type : STRING,\n default: null,\n },\n sourceVersion: {\n type : STRING,\n default: null,\n },\n streamVersion: {\n type : STRING,\n default: null,\n },\n valueVersion: {\n type : STRING,\n default: null,\n },\n channelName: {\n type : STRING,\n allowNull: true,\n default : null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Claim.associate = db => {\n Claim.belongsTo(db.File, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {\n logger.debug(`Claim.getShortClaimIdFromLongClaimId for ${claimName}#${claimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: claimName },\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n throw new Error('No claim(s) found with that claim name');\n default:\n resolve(returnShortId(result, claimId));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getAllChannelClaims = function (channelClaimId) {\n logger.debug(`Claim.getAllChannelClaims for ${channelClaimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { certificateId: channelClaimId },\n order: [['height', 'ASC']],\n raw : true, // returns an array of only data, not an array of instances\n })\n .then(channelClaimsArray => {\n // logger.debug('channelclaimsarray length:', channelClaimsArray.length);\n switch (channelClaimsArray.length) {\n case 0:\n return resolve(null);\n default:\n channelClaimsArray.forEach(claim => {\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n return claim;\n });\n return resolve(channelClaimsArray);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {\n logger.debug(`finding claim id for claim ${claimName} from channel ${channelClaimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: claimName, certificateId: channelClaimId },\n order: [['id', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(result[0].claimId);\n default:\n logger.error(`${result.length} records found for \"${claimName}\" in channel \"${channelClaimId}\"`);\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {\n name,\n claimId: {\n $like: `${shortId}%`,\n }},\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default: // note results must be sorted\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getTopFreeClaimIdByClaimName = function (name) {\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']], // note: maybe height and effective amount need to switch?\n })\n .then(result => {\n logger.debug('length of result', result.length);\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].dataValues.claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.validateLongClaimId = function (name, claimId) {\n return new Promise((resolve, reject) => {\n this.findOne({\n where: {name, claimId},\n })\n .then(result => {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimId = function (claimName, claimId) {\n logger.debug(`getLongClaimId(${claimName}, ${claimId})`);\n if (claimId && (claimId.length === 40)) { // if a full claim id is provided\n return this.validateLongClaimId(claimName, claimId);\n } else if (claimId && claimId.length < 40) {\n return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided\n } else {\n return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided\n }\n };\n\n Claim.resolveClaim = function (name, claimId) {\n logger.debug(`Claim.resolveClaim: ${name} ${claimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name, claimId },\n })\n .then(claimArray => {\n switch (claimArray.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(prepareClaimData(claimArray[0].dataValues));\n default:\n logger.error(`more than one record matches ${name}#${claimId} in db.Claim`);\n return resolve(prepareClaimData(claimArray[0].dataValues));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n return Claim;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/claim.js","module.exports = (sequelize, { STRING, BOOLEAN, INTEGER }) => {\n const File = sequelize.define(\n 'File',\n {\n name: {\n type : STRING,\n allowNull: false,\n },\n claimId: {\n type : STRING,\n allowNull: false,\n },\n address: {\n type : STRING,\n allowNull: false,\n },\n outpoint: {\n type : STRING,\n allowNull: false,\n },\n height: {\n type : INTEGER,\n allowNull: false,\n default : 0,\n },\n fileName: {\n type : STRING,\n allowNull: false,\n },\n filePath: {\n type : STRING,\n allowNull: false,\n },\n fileType: {\n type: STRING,\n },\n nsfw: {\n type : BOOLEAN,\n allowNull : false,\n defaultValue: false,\n },\n trendingEligible: {\n type : BOOLEAN,\n allowNull : false,\n defaultValue: true,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n File.associate = db => {\n File.hasMany(db.Request);\n File.hasOne(db.Claim);\n };\n\n File.getRecentClaims = function () {\n return this.findAll({\n where: { nsfw: false, trendingEligible: true },\n order: [['createdAt', 'DESC']],\n limit: 25,\n });\n };\n\n return File;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/file.js","module.exports = (sequelize, { STRING, BOOLEAN, TEXT }) => {\n const Request = sequelize.define(\n 'Request',\n {\n action: {\n type : STRING,\n allowNull: false,\n },\n url: {\n type : STRING,\n allowNull: false,\n },\n ipAddress: {\n type : STRING,\n allowNull: true,\n },\n result: {\n type : TEXT('long'),\n allowNull: true,\n default : null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Request.associate = db => {\n Request.belongsTo(db.File, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n return Request;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/request.js","'use strict';\nconst bcrypt = require('bcrypt');\nconst logger = require('winston');\n\nmodule.exports = (sequelize, { STRING }) => {\n const User = sequelize.define(\n 'User',\n {\n userName: {\n type : STRING,\n allowNull: false,\n },\n password: {\n type : STRING,\n allowNull: false,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n User.associate = db => {\n User.hasOne(db.Channel);\n };\n\n User.prototype.comparePassword = function (password) {\n return bcrypt.compare(password, this.password);\n };\n\n User.prototype.changePassword = function (newPassword) {\n return new Promise((resolve, reject) => {\n // generate a salt string to use for hashing\n bcrypt.genSalt((saltError, salt) => {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(newPassword, salt, (hashError, hash) => {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the current password with the new hash\n this\n .update({password: hash})\n .then(() => {\n resolve();\n })\n .catch(error => {\n reject(error);\n });\n });\n });\n });\n };\n\n // pre-save hook method to hash the user's password before the user's info is saved to the db.\n User.hook('beforeCreate', (user, options) => {\n logger.debug('User.beforeCreate hook...');\n return new Promise((resolve, reject) => {\n // generate a salt string to use for hashing\n bcrypt.genSalt((saltError, salt) => {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(user.password, salt, (hashError, hash) => {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the password string with the hash password value\n user.password = hash;\n resolve();\n });\n });\n });\n });\n\n return User;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/user.js","module.exports = require(\"bcrypt\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"bcrypt\"\n// module id = 20\n// module chunks = 0","const logger = require('winston');\nconst db = require('../models');\nconst lbryApi = require('../helpers/lbryApi.js');\nconst publishHelpers = require('../helpers/publishHelpers.js');\nconst { publishing: { primaryClaimAddress, additionalClaimAddresses } } = require('../../config/siteConfig.js');\nconst Sequelize = require('sequelize');\nconst Op = Sequelize.Op;\n\nmodule.exports = {\n publish (publishParams, fileName, fileType) {\n return new Promise((resolve, reject) => {\n let publishResults, certificateId, channelName;\n // publish the file\n return lbryApi.publishClaim(publishParams)\n .then(tx => {\n logger.info(`Successfully published ${publishParams.name} ${fileName}`, tx);\n publishResults = tx;\n // get the channel information\n if (publishParams.channel_name) {\n logger.debug(`this claim was published in channel: ${publishParams.channel_name}`);\n return db.Channel.findOne({where: {channelName: publishParams.channel_name}});\n } else {\n logger.debug('this claim was not published in a channel');\n return null;\n }\n })\n .then(channel => {\n // set channel information\n certificateId = null;\n channelName = null;\n if (channel) {\n certificateId = channel.channelClaimId;\n channelName = channel.channelName;\n }\n logger.debug(`certificateId: ${certificateId}`);\n })\n .then(() => {\n // create the File record\n const fileRecord = {\n name : publishParams.name,\n claimId : publishResults.claim_id,\n title : publishParams.metadata.title,\n description: publishParams.metadata.description,\n address : publishParams.claim_address,\n outpoint : `${publishResults.txid}:${publishResults.nout}`,\n height : 0,\n fileName,\n filePath : publishParams.file_path,\n fileType,\n nsfw : publishParams.metadata.nsfw,\n };\n // create the Claim record\n const claimRecord = {\n name : publishParams.name,\n claimId : publishResults.claim_id,\n title : publishParams.metadata.title,\n description: publishParams.metadata.description,\n address : publishParams.claim_address,\n thumbnail : publishParams.metadata.thumbnail,\n outpoint : `${publishResults.txid}:${publishResults.nout}`,\n height : 0,\n contentType: fileType,\n nsfw : publishParams.metadata.nsfw,\n amount : publishParams.bid,\n certificateId,\n channelName,\n };\n // upsert criteria\n const upsertCriteria = {\n name : publishParams.name,\n claimId: publishResults.claim_id,\n };\n // upsert the records\n return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);\n })\n .then(([file, claim]) => {\n logger.debug('File and Claim records successfully created');\n return Promise.all([file.setClaim(claim), claim.setFile(file)]);\n })\n .then(() => {\n logger.debug('File and Claim records successfully associated');\n resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;\n })\n .catch(error => {\n logger.error('PUBLISH ERROR', error);\n publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file\n reject(error);\n });\n });\n },\n claimNameIsAvailable (name) {\n const claimAddresses = additionalClaimAddresses || [];\n claimAddresses.push(primaryClaimAddress);\n // find any records where the name is used\n return db.Claim\n .findAll({\n attributes: ['address'],\n where : {\n name,\n address: {\n [Op.or]: claimAddresses,\n },\n },\n })\n .then(result => {\n if (result.length >= 1) {\n throw new Error('That claim is already in use');\n };\n return name;\n })\n .catch(error => {\n throw error;\n });\n },\n checkChannelAvailability (name) {\n return db.Channel\n .findAll({\n where: { channelName: name },\n })\n .then(result => {\n if (result.length >= 1) {\n throw new Error('That channel has already been claimed');\n }\n return name;\n })\n .catch(error => {\n throw error;\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/controllers/publishController.js","module.exports = require(\"axios\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"axios\"\n// module id = 22\n// module chunks = 0","const lbryConfig = {\n api: {\n apiHost: 'localhost',\n apiPort: '5279',\n },\n};\n\nmodule.exports = lbryConfig;\n\n\n\n// WEBPACK FOOTER //\n// ./config/lbryConfig.js","module.exports = require(\"universal-analytics\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"universal-analytics\"\n// module id = 24\n// module chunks = 0","module.exports = require(\"fs\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"fs\"\n// module id = 25\n// module chunks = 0","const logger = require('winston');\n\nmodule.exports = {\n handleErrorResponse: function (originalUrl, ip, error, res) {\n logger.error(`Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));\n const [status, message] = module.exports.returnErrorMessageAndStatus(error);\n res\n .status(status)\n .json(module.exports.createErrorResponsePayload(status, message));\n },\n returnErrorMessageAndStatus: function (error) {\n let status, message;\n // check for daemon being turned off\n if (error.code === 'ECONNREFUSED') {\n status = 503;\n message = 'Connection refused. The daemon may not be running.';\n // fallback for everything else\n } else {\n status = 400;\n if (error.message) {\n message = error.message;\n } else {\n message = error;\n };\n };\n return [status, message];\n },\n useObjectPropertiesIfNoKeys: function (err) {\n if (Object.keys(err).length === 0) {\n let newErrorObject = {};\n Object.getOwnPropertyNames(err).forEach((key) => {\n newErrorObject[key] = err[key];\n });\n return newErrorObject;\n }\n return err;\n },\n createErrorResponsePayload (status, message) {\n return {\n status,\n success: false,\n message,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/errorHandlers.js","const db = require('../models');\nconst logger = require('winston');\n\nmodule.exports = {\n authenticateUser (channelName, channelId, channelPassword, user) {\n // case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided\n if (!channelName && !channelId) {\n return {\n channelName : null,\n channelClaimId: null,\n };\n }\n // case: channelName or channel Id are provided with user token\n if (user) {\n if (channelName && channelName !== user.channelName) {\n throw new Error('the provided channel name does not match user credentials');\n }\n if (channelId && channelId !== user.channelClaimId) {\n throw new Error('the provided channel id does not match user credentials');\n }\n return {\n channelName : user.channelName,\n channelClaimId: user.channelClaimId,\n };\n }\n // case: channelName or channel Id are provided with password instead of user token\n if (!channelPassword) throw new Error('no channel password provided');\n return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);\n },\n authenticateChannelCredentials (channelName, channelId, userPassword) {\n return new Promise((resolve, reject) => {\n // hoisted variables\n let channelData;\n // build the params for finding the channel\n let channelFindParams = {};\n if (channelName) channelFindParams['channelName'] = channelName;\n if (channelId) channelFindParams['channelClaimId'] = channelId;\n // find the channel\n db.Channel\n .findOne({\n where: channelFindParams,\n })\n .then(channel => {\n if (!channel) {\n logger.debug('no channel found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n channelData = channel.get();\n logger.debug('channel data:', channelData);\n return db.User.findOne({\n where: { userName: channelData.channelName.substring(1) },\n });\n })\n .then(user => {\n if (!user) {\n logger.debug('no user found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n return user.comparePassword(userPassword);\n })\n .then(isMatch => {\n if (!isMatch) {\n logger.debug('incorrect password');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n logger.debug('...password was a match...');\n resolve(channelData);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/auth/authentication.js","const db = require('../models/index');\nconst logger = require('winston');\nconst { returnPaginatedChannelClaims } = require('../helpers/channelPagination.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\nconst NO_FILE = 'NO_FILE';\n\nmodule.exports = {\n getClaimId (channelName, channelClaimId, name, claimId) {\n if (channelName) {\n return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);\n } else {\n return module.exports.getClaimIdByClaim(name, claimId);\n }\n },\n getClaimIdByClaim (claimName, claimId) {\n logger.debug(`getClaimIdByClaim(${claimName}, ${claimId})`);\n return new Promise((resolve, reject) => {\n db.Claim.getLongClaimId(claimName, claimId)\n .then(longClaimId => {\n if (!longClaimId) {\n resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaimIdByChannel (channelName, channelClaimId, claimName) {\n logger.debug(`getClaimIdByChannel(${channelName}, ${channelClaimId}, ${claimName})`);\n return new Promise((resolve, reject) => {\n db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id\n .then(longChannelId => {\n if (!longChannelId) {\n return [null, null];\n }\n return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id\n })\n .then(([longChannelId, longClaimId]) => {\n if (!longChannelId) {\n return resolve(NO_CHANNEL);\n }\n if (!longClaimId) {\n return resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getChannelData (channelName, channelClaimId, page) {\n return new Promise((resolve, reject) => {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId)\n .then(longChannelClaimId => {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);\n })\n .then(([longChannelClaimId, shortChannelClaimId]) => {\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. return all the channel information\n resolve({\n channelName,\n longChannelClaimId,\n shortChannelClaimId,\n });\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getChannelClaims (channelName, channelClaimId, page) {\n return new Promise((resolve, reject) => {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId)\n .then(longChannelClaimId => {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);\n })\n .then(([longChannelClaimId, channelClaimsArray]) => {\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. format the data for the view, including pagination\n let paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);\n // 4. return all the channel information and contents\n resolve(paginatedChannelViewData);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getLocalFileRecord (claimId, name) {\n return db.File.findOne({where: {claimId, name}})\n .then(file => {\n if (!file) {\n return NO_FILE;\n }\n return file.dataValues;\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/controllers/serveController.js","const CLAIMS_PER_PAGE = 12;\n\nmodule.exports = {\n returnPaginatedChannelClaims (channelName, longChannelClaimId, claims, page) {\n const totalPages = module.exports.determineTotalPages(claims);\n const paginationPage = module.exports.getPageFromQuery(page);\n const viewData = {\n channelName : channelName,\n longChannelClaimId: longChannelClaimId,\n claims : module.exports.extractPageFromClaims(claims, paginationPage),\n previousPage : module.exports.determinePreviousPage(paginationPage),\n currentPage : paginationPage,\n nextPage : module.exports.determineNextPage(totalPages, paginationPage),\n totalPages : totalPages,\n totalResults : module.exports.determineTotalClaims(claims),\n };\n return viewData;\n },\n getPageFromQuery (page) {\n if (page) {\n return parseInt(page);\n }\n return 1;\n },\n extractPageFromClaims (claims, pageNumber) {\n if (!claims) {\n return []; // if no claims, return this default\n }\n // logger.debug('claims is array?', Array.isArray(claims));\n // logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));\n const claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;\n const claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;\n const pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);\n return pageOfClaims;\n },\n determineTotalPages (claims) {\n if (!claims) {\n return 0;\n } else {\n const totalClaims = claims.length;\n if (totalClaims < CLAIMS_PER_PAGE) {\n return 1;\n }\n const fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);\n const remainder = totalClaims % CLAIMS_PER_PAGE;\n if (remainder === 0) {\n return fullPages;\n }\n return fullPages + 1;\n }\n },\n determinePreviousPage (currentPage) {\n if (currentPage === 1) {\n return null;\n }\n return currentPage - 1;\n },\n determineNextPage (totalPages, currentPage) {\n if (currentPage === totalPages) {\n return null;\n }\n return currentPage + 1;\n },\n determineTotalClaims (claims) {\n if (!claims) {\n return 0;\n }\n return claims.length;\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/channelPagination.js","const logger = require('winston');\n\nfunction LoggerConfig () {\n this.logLevel = 'debug';\n this.configure = (config) => {\n if (!config) {\n return console.log('No logger config received.');\n }\n // update values with local config params\n const {logLevel} = config;\n this.logLevel = logLevel;\n // configure the winston logger\n logger.configure({\n transports: [\n new (logger.transports.Console)({\n level : this.logLevel,\n timestamp : false,\n colorize : true,\n prettyPrint : true,\n handleExceptions : true,\n humanReadableUnhandledException: true,\n }),\n ],\n });\n // test all the log levels\n logger.error('Level 0');\n logger.warn('Level 1');\n logger.info('Level 2');\n logger.verbose('Level 3');\n logger.debug('Level 4');\n logger.silly('Level 5');\n };\n};\n\nmodule.exports = new LoggerConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/loggerConfig.js","const winstonSlackWebHook = require('winston-slack-webhook').SlackWebHook;\nconst winston = require('winston');\n\nfunction SlackConfig () {\n this.slackWebHook = 'default';\n this.slackErrorChannel = 'default';\n this.slackInfoChannel = 'default';\n this.configure = (config) => {\n if (!config) {\n return console.log('No slack config received.');\n }\n // update variables\n const {slackWebHook, slackErrorChannel, slackInfoChannel} = config;\n this.slackWebHook = slackWebHook;\n this.slackErrorChannel = slackErrorChannel;\n this.slackInfoChannel = slackInfoChannel;\n // update slack webhook settings\n if (this.slackWebHook) {\n // add a transport for errors to slack\n if (this.slackErrorChannel) {\n winston.add(winstonSlackWebHook, {\n name : 'slack-errors-transport',\n level : 'warn',\n webhookUrl: this.slackWebHook,\n channel : this.slackErrorChannel,\n username : 'spee.ch',\n iconEmoji : ':face_with_head_bandage:',\n });\n };\n if (slackInfoChannel) {\n winston.add(winstonSlackWebHook, {\n name : 'slack-info-transport',\n level : 'info',\n webhookUrl: this.slackWebHook,\n channel : this.slackInfoChannel,\n username : 'spee.ch',\n iconEmoji : ':nerd_face:',\n });\n };\n // send test messages\n winston.error('Slack \"error\" logging is online.');\n winston.info('Slack \"info\" logging is online.');\n } else {\n winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');\n }\n };\n};\n\nmodule.exports = new SlackConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/slackConfig.js","module.exports = require(\"winston-slack-webhook\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"winston-slack-webhook\"\n// module id = 32\n// module chunks = 0"],"sourceRoot":""}