diff --git a/client/src/api/assetApi.js b/client/src/api/assetApi.js index 0750b572..2c8779b1 100644 --- a/client/src/api/assetApi.js +++ b/client/src/api/assetApi.js @@ -1,6 +1,6 @@ import Request from '../utils/request'; -export function getLongClaimId (host, name, modifier) { +export function getLongClaimId(host, name, modifier) { let body = {}; // create request params if (modifier) { @@ -13,40 +13,40 @@ export function getLongClaimId (host, name, modifier) { } body['claimName'] = name; const params = { - method : 'POST', + method: 'POST', headers: { 'Content-Type': 'application/json' }, - body : JSON.stringify(body), + body: JSON.stringify(body), }; // create url const url = `${host}/api/claim/long-id`; // return the request promise return Request(url, params); -}; +} -export function getShortId (host, name, claimId) { +export function getShortId(host, name, claimId) { const url = `${host}/api/claim/short-id/${claimId}/${name}`; return Request(url); -}; +} -export function getClaimData (host, name, claimId) { +export function getClaimData(host, name, claimId) { const url = `${host}/api/claim/data/${name}/${claimId}`; return Request(url); -}; +} -export function checkClaimAvailability (claim) { +export function checkClaimAvailability(claim) { const url = `/api/claim/availability/${claim}`; return Request(url); } -export function getClaimViews (claimId) { +export function getClaimViews(claimId) { const url = `/api/claim/views/${claimId}`; return Request(url); } -export function doAbandonClaim (claimId) { +export function doAbandonClaim(outpoint) { const params = { - method : 'POST', - body : JSON.stringify({claimId}), + method: 'POST', + body: JSON.stringify({ outpoint }), headers: new Headers({ 'Content-Type': 'application/json', }), diff --git a/client/src/channels/publish.js b/client/src/channels/publish.js index 0a89feb4..87f69f67 100644 --- a/client/src/channels/publish.js +++ b/client/src/channels/publish.js @@ -22,14 +22,29 @@ export const makePublishRequestChannel = (fd, isUpdate) => { xhr.upload.addEventListener('load', onLoad); // set state change handler xhr.onreadystatechange = () => { - if (xhr.readyState === 4) { - const response = JSON.parse(xhr.response); - if ((xhr.status === 200) && response.success) { - emitter({success: response}); - emitter(END); - } else { - emitter({error: new Error(response.message)}); - emitter(END); + if (xhr.readyState === XMLHttpRequest.DONE) { + switch (xhr.status) { + case 413: + emitter({error: new Error("Unfortunately it appears this web server " + + "has been misconfigured, please inform the service administrators " + + "that they must set their nginx/apache request size maximums higher " + + "than their file size limits.")}); + emitter(END); + break; + case 200: + var response = JSON.parse(xhr.response); + if (response.success) { + emitter({success: response}); + emitter(END); + } else { + emitter({error: new Error(response.message)}); + emitter(END); + } + break; + default: + emitter({error: new Error("Received an unexpected response from " + + "server: " + xhr.status)}); + emitter(END); } } }; diff --git a/client/src/sagas/abandon.js b/client/src/sagas/abandon.js index db290274..51f73d15 100644 --- a/client/src/sagas/abandon.js +++ b/client/src/sagas/abandon.js @@ -5,17 +5,19 @@ import { updatePublishStatus, clearFile } from '../actions/publish'; import { removeAsset } from '../actions/show'; import { doAbandonClaim } from '../api/assetApi'; -function * abandonClaim (action) { +function* abandonClaim(action) { const { claimData, history } = action.data; - const { claimId } = claimData; + const { outpoint } = claimData; - const confirm = window.confirm('Are you sure you want to abandon this claim? This action cannot be undone.'); + const confirm = window.confirm( + 'Are you sure you want to abandon this claim? This action cannot be undone.' + ); if (!confirm) return; yield put(updatePublishStatus(publishStates.ABANDONING, 'Your claim is being abandoned...')); try { - yield call(doAbandonClaim, claimId); + yield call(doAbandonClaim, outpoint); } catch (error) { return console.log('abandon error:', error.message); } @@ -25,6 +27,6 @@ function * abandonClaim (action) { return history.push('/'); } -export function * watchAbandonClaim () { +export function* watchAbandonClaim() { yield takeLatest(actions.ABANDON_CLAIM, abandonClaim); -}; +} diff --git a/server/controllers/api/claim/abandon/index.js b/server/controllers/api/claim/abandon/index.js index 08a6505f..f808cd2e 100644 --- a/server/controllers/api/claim/abandon/index.js +++ b/server/controllers/api/claim/abandon/index.js @@ -9,28 +9,28 @@ const authenticateUser = require('../publish/authentication.js'); */ const claimAbandon = async (req, res) => { - const {claimId} = req.body; - const {user} = req; + const { outpoint } = req.body; + const { user } = req; try { const [channel, claim] = await Promise.all([ authenticateUser(user.channelName, null, null, user), - db.Claim.findOne({where: {claimId}}), + db.Claim.findOne({ where: { outpoint } }), ]); if (!claim) throw new Error('That channel does not exist'); - if (!channel.channelName) throw new Error('You don\'t own this channel'); + if (!channel.channelName) throw new Error("You don't own this channel"); - await abandonClaim({claimId}); - const file = await db.File.findOne({where: {claimId}}); + await abandonClaim({ outpoint }); + const file = await db.File.findOne({ where: { outpoint } }); await Promise.all([ deleteFile(file.filePath), - db.File.destroy({where: {claimId}}), - db.Claim.destroy({where: {claimId}}), + db.File.destroy({ where: { outpoint } }), + db.Claim.destroy({ where: { outpoint } }), ]); - logger.debug(`Claim abandoned: ${claimId}`); + logger.debug(`Claim abandoned: ${outpoint}`); res.status(200).json({ success: true, - message: `Claim with id ${claimId} abandonded`, + message: `Claim with outpoint ${outpoint} abandonded`, }); } catch (error) { logger.error('abandon claim error:', error); diff --git a/server/index.js b/server/index.js index e3806779..87455cea 100644 --- a/server/index.js +++ b/server/index.js @@ -20,10 +20,7 @@ const { setupBlockList } = require('./utils/blockList'); const speechPassport = require('./speechPassport'); const processTrending = require('./utils/processTrending'); -const { - logMetricsMiddleware, - setRouteDataInContextMiddleware, -} = require('./middleware/logMetricsMiddleware'); +const { setRouteDataInContextMiddleware } = require('./middleware/httpContextMiddleware'); const { details: { port: PORT, blockListEndpoint }, @@ -145,7 +142,7 @@ function Server() { app[routeMethod]( routePath, - logMetricsMiddleware, + // logMetricsMiddleware, setRouteDataInContextMiddleware(routePath, routeData), ...controllers ); diff --git a/server/lbrynet/index.js b/server/lbrynet/index.js index 1beea877..60626792 100644 --- a/server/lbrynet/index.js +++ b/server/lbrynet/index.js @@ -73,13 +73,14 @@ module.exports = { }); }); }, - async abandonClaim({ claimId }) { - logger.debug(`lbryApi >> Abandon claim "${claimId}"`); + async abandonClaim({ outpoint }) { + logger.debug(`lbryApi >> Abandon claim "${outpoint}"`); const gaStartTime = Date.now(); + const [txid, nout] = outpoint.split(':'); try { const abandon = await axios.post(lbrynetUri, { - method: 'claim_abandon', - params: { claim_id: claimId }, + method: 'stream_abandon', + params: { txid: txid, nout: Number(nout) }, }); sendGATimingEvent('lbrynet', 'abandonClaim', 'ABANDON_CLAIM', gaStartTime, Date.now()); return abandon.data; diff --git a/server/middleware/autoblockPublishMiddleware.js b/server/middleware/autoblockPublishMiddleware.js index 426323a1..5238280b 100644 --- a/server/middleware/autoblockPublishMiddleware.js +++ b/server/middleware/autoblockPublishMiddleware.js @@ -7,7 +7,7 @@ const { const ipBanFile = './site/config/ipBan.txt'; const forbiddenMessage = '

Forbidden

If you are seeing this by mistake, please contact us using https://chat.lbry.com/'; - +const maxPublishesInTenMinutes = 20; let ipCounts = {}; let blockedAddresses = []; @@ -44,7 +44,7 @@ const autoblockPublishMiddleware = (req, res, next) => { } }, 600000 /* 10 minute retainer */); - if (count === 10) { + if (count === maxPublishesInTenMinutes) { logger.error(`Banning IP: ${ip}`); blockedAddresses.push(ip); res.status(403).send(forbiddenMessage); diff --git a/server/middleware/httpContextMiddleware.js b/server/middleware/httpContextMiddleware.js new file mode 100644 index 00000000..b41c602f --- /dev/null +++ b/server/middleware/httpContextMiddleware.js @@ -0,0 +1,13 @@ +const httpContext = require('express-http-context'); + +function setRouteDataInContextMiddleware(routePath, routeData) { + return function(req, res, next) { + httpContext.set('routePath', routePath); + httpContext.set('routeData', routeData); + next(); + }; +} + +module.exports = { + setRouteDataInContextMiddleware, +};