From 9523890b65259f62e493e10312e61dc20fc10f78 Mon Sep 17 00:00:00 2001 From: bill bittner <bittner.w@gmail.com> Date: Thu, 29 Mar 2018 11:24:52 -0700 Subject: [PATCH] fixed api and assets routes --- server/helpers/multipartMiddleware.js | 5 + server/routes/api/channelAvailability.js | 22 ++-- server/routes/api/channelClaims.js | 32 +++--- server/routes/api/channelData.js | 30 +++-- server/routes/api/channelShortId.js | 19 ++-- server/routes/api/claimAvailability.js | 22 ++-- server/routes/api/claimData.js | 31 +++--- server/routes/api/claimGet.js | 51 +++++---- server/routes/api/claimList.js | 18 ++- server/routes/api/claimLongId.js | 38 +++---- server/routes/api/claimPublish.js | 104 +++++++++--------- server/routes/api/claimResolve.js | 18 ++- server/routes/api/claimShortId.js | 19 ++-- server/routes/api/fileAvailability.js | 42 ++++--- server/routes/api/index.js | 33 +++--- server/routes/asset/serveAssetByClaim.js | 44 -------- .../asset/serveAssetByIdentifierAndClaim.js | 55 --------- server/routes/{asset => assets}/index.js | 7 +- server/routes/assets/serveAssetByClaim.js | 42 +++++++ .../assets/serveAssetByIdentifierAndClaim.js | 58 ++++++++++ server/routes/{page => pages}/index.js | 0 server/routes/{page => pages}/redirect.js | 0 .../routes/{page => pages}/sendEmbedPage.js | 0 server/routes/{page => pages}/sendReactApp.js | 0 server/server.js | 98 +++++++++++++++++ speech.js | 4 +- 26 files changed, 439 insertions(+), 353 deletions(-) create mode 100644 server/helpers/multipartMiddleware.js delete mode 100644 server/routes/asset/serveAssetByClaim.js delete mode 100644 server/routes/asset/serveAssetByIdentifierAndClaim.js rename server/routes/{asset => assets}/index.js (51%) create mode 100644 server/routes/assets/serveAssetByClaim.js create mode 100644 server/routes/assets/serveAssetByIdentifierAndClaim.js rename server/routes/{page => pages}/index.js (100%) rename server/routes/{page => pages}/redirect.js (100%) rename server/routes/{page => pages}/sendEmbedPage.js (100%) rename server/routes/{page => pages}/sendReactApp.js (100%) create mode 100644 server/server.js diff --git a/server/helpers/multipartMiddleware.js b/server/helpers/multipartMiddleware.js new file mode 100644 index 00000000..c483754b --- /dev/null +++ b/server/helpers/multipartMiddleware.js @@ -0,0 +1,5 @@ +const multipart = require('connect-multiparty'); +const { publishing: { uploadDirectory } } = require('siteConfig.js'); +const multipartMiddleware = multipart({uploadDir: uploadDirectory}); + +module.exports = multipartMiddleware; diff --git a/server/routes/api/channelAvailability.js b/server/routes/api/channelAvailability.js index d008b445..128aff44 100644 --- a/server/routes/api/channelAvailability.js +++ b/server/routes/api/channelAvailability.js @@ -8,18 +8,16 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const channelAvailability = () => { - return ({ ip, originalUrl, params: { name } }, res) => { - const gaStartTime = Date.now(); - checkChannelAvailability(name) - .then(availableName => { - res.status(200).json(availableName); - sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now()); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const channelAvailability = ({ ip, originalUrl, params: { name } }, res) => { + const gaStartTime = Date.now(); + checkChannelAvailability(name) + .then(availableName => { + res.status(200).json(availableName); + sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now()); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = channelAvailability; diff --git a/server/routes/api/channelClaims.js b/server/routes/api/channelClaims.js index 84c44442..8f99a148 100644 --- a/server/routes/api/channelClaims.js +++ b/server/routes/api/channelClaims.js @@ -9,23 +9,21 @@ const NO_CHANNEL = 'NO_CHANNEL'; */ -const channelClaims = () => { - return ({ ip, originalUrl, body, params }, res) => { - const channelName = params.channelName; - let channelClaimId = params.channelClaimId; - if (channelClaimId === 'none') channelClaimId = null; - const page = params.page; - getChannelClaims(channelName, channelClaimId, page) - .then(data => { - if (data === NO_CHANNEL) { - return res.status(404).json({success: false, message: 'No matching channel was found'}); - } - res.status(200).json({success: true, data}); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const channelClaims = ({ ip, originalUrl, body, params }, res) => { + const channelName = params.channelName; + let channelClaimId = params.channelClaimId; + if (channelClaimId === 'none') channelClaimId = null; + const page = params.page; + getChannelClaims(channelName, channelClaimId, page) + .then(data => { + if (data === NO_CHANNEL) { + return res.status(404).json({success: false, message: 'No matching channel was found'}); + } + res.status(200).json({success: true, data}); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = channelClaims; diff --git a/server/routes/api/channelData.js b/server/routes/api/channelData.js index 5ce66b48..d6a3f026 100644 --- a/server/routes/api/channelData.js +++ b/server/routes/api/channelData.js @@ -9,22 +9,20 @@ const NO_CHANNEL = 'NO_CHANNEL'; */ -const channelData = () => { - return ({ ip, originalUrl, body, params }, res) => { - const channelName = params.channelName; - let channelClaimId = params.channelClaimId; - if (channelClaimId === 'none') channelClaimId = null; - getChannelData(channelName, channelClaimId, 0) - .then(data => { - if (data === NO_CHANNEL) { - return res.status(404).json({success: false, message: 'No matching channel was found'}); - } - res.status(200).json({success: true, data}); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const channelData = ({ ip, originalUrl, body, params }, res) => { + const channelName = params.channelName; + let channelClaimId = params.channelClaimId; + if (channelClaimId === 'none') channelClaimId = null; + getChannelData(channelName, channelClaimId, 0) + .then(data => { + if (data === NO_CHANNEL) { + return res.status(404).json({success: false, message: 'No matching channel was found'}); + } + res.status(200).json({success: true, data}); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = channelData; diff --git a/server/routes/api/channelShortId.js b/server/routes/api/channelShortId.js index 15b4e655..0e6b17ec 100644 --- a/server/routes/api/channelShortId.js +++ b/server/routes/api/channelShortId.js @@ -1,4 +1,5 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); +const db = require('models'); /* @@ -6,16 +7,14 @@ route to get a short channel id from long channel Id */ -const channelShortIdRoute = (db) => { - return ({ ip, originalUrl, params }, res) => { - db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name) - .then(shortId => { - res.status(200).json(shortId); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const channelShortIdRoute = ({ ip, originalUrl, params }, res) => { + db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name) + .then(shortId => { + res.status(200).json(shortId); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = channelShortIdRoute; diff --git a/server/routes/api/claimAvailability.js b/server/routes/api/claimAvailability.js index 82e76af5..5138d1d7 100644 --- a/server/routes/api/claimAvailability.js +++ b/server/routes/api/claimAvailability.js @@ -8,18 +8,16 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const claimAvailability = () => { - return ({ ip, originalUrl, params: { name } }, res) => { - const gaStartTime = Date.now(); - claimNameIsAvailable(name) - .then(result => { - res.status(200).json(result); - sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now()); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const claimAvailability = ({ ip, originalUrl, params: { name } }, res) => { + const gaStartTime = Date.now(); + claimNameIsAvailable(name) + .then(result => { + res.status(200).json(result); + sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now()); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimAvailability; diff --git a/server/routes/api/claimData.js b/server/routes/api/claimData.js index 0d307faa..d8b6c448 100644 --- a/server/routes/api/claimData.js +++ b/server/routes/api/claimData.js @@ -1,4 +1,5 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); +const db = require('models'); /* @@ -6,22 +7,20 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const claimData = (db) => { - return ({ ip, originalUrl, body, params }, res) => { - const claimName = params.claimName; - let claimId = params.claimId; - if (claimId === 'none') claimId = null; - db.Claim.resolveClaim(claimName, claimId) - .then(claimInfo => { - if (!claimInfo) { - return res.status(404).json({success: false, message: 'No claim could be found'}); - } - res.status(200).json({success: true, data: claimInfo}); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const claimData = ({ ip, originalUrl, body, params }, res) => { + const claimName = params.claimName; + let claimId = params.claimId; + if (claimId === 'none') claimId = null; + db.Claim.resolveClaim(claimName, claimId) + .then(claimInfo => { + if (!claimInfo) { + return res.status(404).json({success: false, message: 'No claim could be found'}); + } + res.status(200).json({success: true, data: claimInfo}); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimData; diff --git a/server/routes/api/claimGet.js b/server/routes/api/claimGet.js index 1fbfafe2..0d066140 100644 --- a/server/routes/api/claimGet.js +++ b/server/routes/api/claimGet.js @@ -1,6 +1,7 @@ const { getClaim } = require('helpers/lbryApi.js'); const { addGetResultsToFileData, createFileData } = require('../../helpers/publishHelpers.js'); const { handleErrorResponse } = require('helpers/errorHandlers.js'); +const db = require('models'); /* @@ -8,32 +9,30 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const claimGet = (db) => { - return ({ ip, originalUrl, params }, res) => { - const name = params.name; - const claimId = params.claimId; - // resolve the claim - db.Claim.resolveClaim(name, claimId) - .then(resolveResult => { - // make sure a claim actually exists at that uri - if (!resolveResult) { - throw new Error('No matching uri found in Claim table'); - } - let fileData = createFileData(resolveResult); - // get the claim - return Promise.all([fileData, getClaim(`${name}#${claimId}`)]); - }) - .then(([ fileData, getResult ]) => { - fileData = addGetResultsToFileData(fileData, getResult); - return Promise.all([db.upsert(db.File, fileData, {name, claimId}, 'File'), getResult]); - }) - .then(([ fileRecord, {message, completed} ]) => { - res.status(200).json({ success: true, message, completed }); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const claimGet = ({ ip, originalUrl, params }, res) => { + const name = params.name; + const claimId = params.claimId; + // resolve the claim + db.Claim.resolveClaim(name, claimId) + .then(resolveResult => { + // make sure a claim actually exists at that uri + if (!resolveResult) { + throw new Error('No matching uri found in Claim table'); + } + let fileData = createFileData(resolveResult); + // get the claim + return Promise.all([fileData, getClaim(`${name}#${claimId}`)]); + }) + .then(([ fileData, getResult ]) => { + fileData = addGetResultsToFileData(fileData, getResult); + return Promise.all([db.upsert(db.File, fileData, {name, claimId}, 'File'), getResult]); + }) + .then(([ fileRecord, {message, completed} ]) => { + res.status(200).json({ success: true, message, completed }); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimGet; diff --git a/server/routes/api/claimList.js b/server/routes/api/claimList.js index fc1d124a..6cd7a349 100644 --- a/server/routes/api/claimList.js +++ b/server/routes/api/claimList.js @@ -7,16 +7,14 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const claimList = (db) => { - return ({ ip, originalUrl, params }, res) => { - getClaimList(params.name) - .then(claimsList => { - res.status(200).json(claimsList); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const claimList = ({ ip, originalUrl, params }, res) => { + getClaimList(params.name) + .then(claimsList => { + res.status(200).json(claimsList); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimList; diff --git a/server/routes/api/claimLongId.js b/server/routes/api/claimLongId.js index a4caebc2..98e80770 100644 --- a/server/routes/api/claimLongId.js +++ b/server/routes/api/claimLongId.js @@ -10,26 +10,24 @@ const NO_CLAIM = 'NO_CLAIM'; */ -const claimLongId = () => { - return ({ ip, originalUrl, body, params }, res) => { - const channelName = body.channelName; - const channelClaimId = body.channelClaimId; - const claimName = body.claimName; - const claimId = body.claimId; - getClaimId(channelName, channelClaimId, claimName, claimId) - .then(result => { - if (result === NO_CHANNEL) { - return res.status(404).json({success: false, message: 'No matching channel could be found'}); - } - if (result === NO_CLAIM) { - return res.status(404).json({success: false, message: 'No matching claim id could be found'}); - } - res.status(200).json({success: true, data: result}); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const claimLongId = ({ ip, originalUrl, body, params }, res) => { + const channelName = body.channelName; + const channelClaimId = body.channelClaimId; + const claimName = body.claimName; + const claimId = body.claimId; + getClaimId(channelName, channelClaimId, claimName, claimId) + .then(result => { + if (result === NO_CHANNEL) { + return res.status(404).json({success: false, message: 'No matching channel could be found'}); + } + if (result === NO_CLAIM) { + return res.status(404).json({success: false, message: 'No matching claim id could be found'}); + } + res.status(200).json({success: true, data: result}); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimLongId; diff --git a/server/routes/api/claimPublish.js b/server/routes/api/claimPublish.js index d5f4dff5..5d5b1e52 100644 --- a/server/routes/api/claimPublish.js +++ b/server/routes/api/claimPublish.js @@ -11,60 +11,58 @@ const { details: { host } } = require('siteConfig.js'); */ -const claimPublish = (db) => { - return ({ body, files, headers, ip, originalUrl, user }, res) => { - // define variables - let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title; - // record the start time of the request - gaStartTime = Date.now(); - // validate the body and files of the request - try { - // validateApiPublishRequest(body, files); - ({name, nsfw, license, title, description, thumbnail} = parsePublishApiRequestBody(body)); - ({fileName, filePath, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType} = parsePublishApiRequestFiles(files)); - ({channelName, channelId, channelPassword} = body); - } catch (error) { - return res.status(400).json({success: false, message: error.message}); - } - // check channel authorization - Promise - .all([ - authenticateUser(channelName, channelId, channelPassword, user), - claimNameIsAvailable(name), - createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail), - createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw), - ]) - .then(([{channelName, channelClaimId}, validatedClaimName, publishParams, thumbnailPublishParams]) => { - // add channel details to the publish params - if (channelName && channelClaimId) { - publishParams['channel_name'] = channelName; - publishParams['channel_id'] = channelClaimId; - } - // publish the thumbnail - if (thumbnailPublishParams) { - publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType); - } - // publish the asset - return publish(publishParams, fileName, fileType); - }) - .then(result => { - res.status(200).json({ - success: true, - message: 'publish completed successfully', - data : { - name, - claimId: result.claim_id, - url : `${host}/${result.claim_id}/${name}`, - lbryTx : result, - }, - }); - // record the publish end time and send to google analytics - sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now()); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); +const claimPublish = ({ body, files, headers, ip, originalUrl, user }, res) => { + // define variables + let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title; + // record the start time of the request + gaStartTime = Date.now(); + // validate the body and files of the request + try { + // validateApiPublishRequest(body, files); + ({name, nsfw, license, title, description, thumbnail} = parsePublishApiRequestBody(body)); + ({fileName, filePath, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType} = parsePublishApiRequestFiles(files)); + ({channelName, channelId, channelPassword} = body); + } catch (error) { + return res.status(400).json({success: false, message: error.message}); + } + // check channel authorization + Promise + .all([ + authenticateUser(channelName, channelId, channelPassword, user), + claimNameIsAvailable(name), + createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail), + createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw), + ]) + .then(([{channelName, channelClaimId}, validatedClaimName, publishParams, thumbnailPublishParams]) => { + // add channel details to the publish params + if (channelName && channelClaimId) { + publishParams['channel_name'] = channelName; + publishParams['channel_id'] = channelClaimId; + } + // publish the thumbnail + if (thumbnailPublishParams) { + publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType); + } + // publish the asset + return publish(publishParams, fileName, fileType); + }) + .then(result => { + res.status(200).json({ + success: true, + message: 'publish completed successfully', + data : { + name, + claimId: result.claim_id, + url : `${host}/${result.claim_id}/${name}`, + lbryTx : result, + }, }); - }; + // record the publish end time and send to google analytics + sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now()); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimPublish; diff --git a/server/routes/api/claimResolve.js b/server/routes/api/claimResolve.js index 1b9cec12..5cf03b3f 100644 --- a/server/routes/api/claimResolve.js +++ b/server/routes/api/claimResolve.js @@ -7,16 +7,14 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const claimResolve = () => { - return ({ headers, ip, originalUrl, params }, res) => { - resolveUri(`${params.name}#${params.claimId}`) - .then(resolvedUri => { - res.status(200).json(resolvedUri); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const claimResolve = ({ headers, ip, originalUrl, params }, res) => { + resolveUri(`${params.name}#${params.claimId}`) + .then(resolvedUri => { + res.status(200).json(resolvedUri); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimResolve; diff --git a/server/routes/api/claimShortId.js b/server/routes/api/claimShortId.js index e6983a78..a8a310d2 100644 --- a/server/routes/api/claimShortId.js +++ b/server/routes/api/claimShortId.js @@ -1,4 +1,5 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); +const db = require('models'); /* @@ -6,16 +7,14 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const claimShortId = (db) => { - return ({ ip, originalUrl, body, params }, res) => { - db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name) - .then(shortId => { - res.status(200).json({success: true, data: shortId}); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const claimShortId = ({ ip, originalUrl, body, params }, res) => { + db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name) + .then(shortId => { + res.status(200).json({success: true, data: shortId}); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = claimShortId; diff --git a/server/routes/api/fileAvailability.js b/server/routes/api/fileAvailability.js index 11357f1a..650bdf6b 100644 --- a/server/routes/api/fileAvailability.js +++ b/server/routes/api/fileAvailability.js @@ -1,5 +1,5 @@ - const { handleErrorResponse } = require('helpers/errorHandlers.js'); +const db = require('models'); /* @@ -7,27 +7,25 @@ const { handleErrorResponse } = require('helpers/errorHandlers.js'); */ -const fileAvailability = (db) => { - return ({ ip, originalUrl, params }, res) => { - const name = params.name; - const claimId = params.claimId; - db.File - .findOne({ - where: { - name, - claimId, - }, - }) - .then(result => { - if (result) { - return res.status(200).json({success: true, data: true}); - } - res.status(200).json({success: true, data: false}); - }) - .catch(error => { - handleErrorResponse(originalUrl, ip, error, res); - }); - }; +const fileAvailability = ({ ip, originalUrl, params }, res) => { + const name = params.name; + const claimId = params.claimId; + db.File + .findOne({ + where: { + name, + claimId, + }, + }) + .then(result => { + if (result) { + return res.status(200).json({success: true, data: true}); + } + res.status(200).json({success: true, data: false}); + }) + .catch(error => { + handleErrorResponse(originalUrl, ip, error, res); + }); }; module.exports = fileAvailability; diff --git a/server/routes/api/index.js b/server/routes/api/index.js index e15046d3..8679ab78 100644 --- a/server/routes/api/index.js +++ b/server/routes/api/index.js @@ -12,18 +12,23 @@ const claimShortId = require('./claimShortId'); const claimList = require('./claimList'); const fileAvailability = require('./fileAvailability'); -module.exports = { - channelAvailability, - channelClaims, - channelData, - channelShortId, - claimAvailability, - claimData, - claimGet, - claimLongId, - claimPublish, - claimResolve, - claimShortId, - claimList, - fileAvailability, +const multipartMiddleware = require('helpers/multipartMiddleware'); + +module.exports = (app) => { + // channel routes + app.get('/api/channel/availability/:name', channelAvailability); + app.get('/api/channel/short-id/:longId/:name', channelShortId); + app.get('/api/channel/data/:channelName/:channelClaimId', channelData); + app.get('/api/channel/claims/:channelName/:channelClaimId/:page', channelClaims); + // claim routes + app.get('/api/claim/list/:name', claimList); + app.get('/api/claim/get/:name/:claimId', claimGet); + app.get('/api/claim/availability/:name', claimAvailability); + app.get('/api/claim/resolve/:name/:claimId', claimResolve); + app.post('/api/claim/publish', multipartMiddleware, claimPublish); + app.get('/api/claim/short-id/:longId/:name', claimShortId); + app.post('/api/claim/long-id', claimLongId); + app.get('/api/claim/data/:claimName/:claimId', claimData); + // file routes + app.get('/api/file/availability/:name/:claimId', fileAvailability); }; diff --git a/server/routes/asset/serveAssetByClaim.js b/server/routes/asset/serveAssetByClaim.js deleted file mode 100644 index 7fe091df..00000000 --- a/server/routes/asset/serveAssetByClaim.js +++ /dev/null @@ -1,44 +0,0 @@ -const { sendGAServeEvent } = require('helpers/googleAnalytics'); -const { determineResponseType, logRequestData, getClaimIdAndServeAsset } = require('helpers/serveHelpers.js'); -const lbryUri = require('helpers/lbryUri.js'); -const handleShowRender = require('helpers/handleShowRender.jsx'); -const SERVE = 'SERVE'; - -/* - - route to serve an asset or the react app via the claim name only - -*/ - -const claim = () => { - return (req, res) => { - const { headers, ip, originalUrl, params } = req; - // decide if this is a show request - let hasFileExtension; - try { - ({ hasFileExtension } = lbryUri.parseModifier(params.claim)); - } catch (error) { - return res.status(400).json({success: false, message: error.message}); - } - let responseType = determineResponseType(hasFileExtension, headers); - if (responseType !== SERVE) { - return handleShowRender(req, res); - } - // handle serve request - // send google analytics - sendGAServeEvent(headers, ip, originalUrl); - // parse the claim - let claimName; - try { - ({claimName} = lbryUri.parseClaim(params.claim)); - } catch (error) { - return res.status(400).json({success: false, message: error.message}); - } - // log the request data for debugging - logRequestData(responseType, claimName, null, null); - // get the claim Id and then serve the asset - getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res); - }; -}; - -module.exports = claim; diff --git a/server/routes/asset/serveAssetByIdentifierAndClaim.js b/server/routes/asset/serveAssetByIdentifierAndClaim.js deleted file mode 100644 index 5c305d51..00000000 --- a/server/routes/asset/serveAssetByIdentifierAndClaim.js +++ /dev/null @@ -1,55 +0,0 @@ -const { sendGAServeEvent } = require('helpers/googleAnalytics'); -const { determineResponseType, flipClaimNameAndIdForBackwardsCompatibility, logRequestData, getClaimIdAndServeAsset } = require('helpers/serveHelpers.js'); -const lbryUri = require('helpers/lbryUri.js'); -const handleShowRender = require('helpers/handleShowRender.jsx'); - -const SERVE = 'SERVE'; - -/* - - route to serve an asset or the react app via the claim name and an identifier - -*/ - -const identifierClaim = () => { - return (req, res) => { - const { headers, ip, originalUrl, params } = req; - // decide if this is a show request - let hasFileExtension; - try { - ({ hasFileExtension } = lbryUri.parseModifier(params.claim)); - } catch (error) { - return res.status(400).json({success: false, message: error.message}); - } - let responseType = determineResponseType(hasFileExtension, headers); - if (responseType !== SERVE) { - return handleShowRender(req, res); - } - // handle serve request - // send google analytics - sendGAServeEvent(headers, ip, originalUrl); - // parse the claim - let claimName; - try { - ({ claimName } = lbryUri.parseClaim(params.claim)); - } catch (error) { - return res.status(400).json({success: false, message: error.message}); - } - // parse the identifier - let isChannel, channelName, channelClaimId, claimId; - try { - ({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(params.identifier)); - } catch (error) { - return res.status(400).json({success: false, message: error.message}); - } - if (!isChannel) { - [claimId, claimName] = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName); - } - // log the request data for debugging - logRequestData(responseType, claimName, channelName, claimId); - // get the claim Id and then serve the asset - getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res); - }; -}; - -module.exports = identifierClaim; diff --git a/server/routes/asset/index.js b/server/routes/assets/index.js similarity index 51% rename from server/routes/asset/index.js rename to server/routes/assets/index.js index d988c234..4f358a74 100644 --- a/server/routes/asset/index.js +++ b/server/routes/assets/index.js @@ -1,8 +1,7 @@ const serveAssetByClaim = require('./serveAssetByClaim'); const serveAssetByIdentifierAndClaim = require('./serveAssetByIdentifierAndClaim'); - -module.exports = { - serveAssetByClaim, - serveAssetByIdentifierAndClaim, +module.exports = (app, db) => { + app.get('/:identifier/:claim', serveAssetByIdentifierAndClaim); + app.get('/:claim', serveAssetByClaim); }; diff --git a/server/routes/assets/serveAssetByClaim.js b/server/routes/assets/serveAssetByClaim.js new file mode 100644 index 00000000..9eec9b93 --- /dev/null +++ b/server/routes/assets/serveAssetByClaim.js @@ -0,0 +1,42 @@ +const { sendGAServeEvent } = require('helpers/googleAnalytics'); +const { determineResponseType, logRequestData, getClaimIdAndServeAsset } = require('helpers/serveHelpers.js'); +const lbryUri = require('helpers/lbryUri.js'); +const handleShowRender = require('helpers/handleShowRender.jsx'); +const SERVE = 'SERVE'; + +/* + + route to serve an asset or the react app via the claim name only + +*/ + +const serverAssetByClaim = (req, res) => { + const { headers, ip, originalUrl, params } = req; + // decide if this is a show request + let hasFileExtension; + try { + ({ hasFileExtension } = lbryUri.parseModifier(params.claim)); + } catch (error) { + return res.status(400).json({success: false, message: error.message}); + } + let responseType = determineResponseType(hasFileExtension, headers); + if (responseType !== SERVE) { + return handleShowRender(req, res); + } + // handle serve request + // send google analytics + sendGAServeEvent(headers, ip, originalUrl); + // parse the claim + let claimName; + try { + ({claimName} = lbryUri.parseClaim(params.claim)); + } catch (error) { + return res.status(400).json({success: false, message: error.message}); + } + // log the request data for debugging + logRequestData(responseType, claimName, null, null); + // get the claim Id and then serve the asset + getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res); +}; + +module.exports = serverAssetByClaim; diff --git a/server/routes/assets/serveAssetByIdentifierAndClaim.js b/server/routes/assets/serveAssetByIdentifierAndClaim.js new file mode 100644 index 00000000..2357b520 --- /dev/null +++ b/server/routes/assets/serveAssetByIdentifierAndClaim.js @@ -0,0 +1,58 @@ +const { sendGAServeEvent } = require('helpers/googleAnalytics'); +const { + determineResponseType, + flipClaimNameAndIdForBackwardsCompatibility, + logRequestData, + getClaimIdAndServeAsset, +} = require('helpers/serveHelpers.js'); +const lbryUri = require('helpers/lbryUri.js'); +const handleShowRender = require('helpers/handleShowRender.jsx'); + +const SERVE = 'SERVE'; + +/* + + route to serve an asset or the react app via the claim name and an identifier + +*/ + +const serverAssetByIdentifierAndClaim = (req, res) => { + const { headers, ip, originalUrl, params } = req; + // decide if this is a show request + let hasFileExtension; + try { + ({ hasFileExtension } = lbryUri.parseModifier(params.claim)); + } catch (error) { + return res.status(400).json({success: false, message: error.message}); + } + let responseType = determineResponseType(hasFileExtension, headers); + if (responseType !== SERVE) { + return handleShowRender(req, res); + } + // handle serve request + // send google analytics + sendGAServeEvent(headers, ip, originalUrl); + // parse the claim + let claimName; + try { + ({ claimName } = lbryUri.parseClaim(params.claim)); + } catch (error) { + return res.status(400).json({success: false, message: error.message}); + } + // parse the identifier + let isChannel, channelName, channelClaimId, claimId; + try { + ({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(params.identifier)); + } catch (error) { + return res.status(400).json({success: false, message: error.message}); + } + if (!isChannel) { + [claimId, claimName] = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName); + } + // log the request data for debugging + logRequestData(responseType, claimName, channelName, claimId); + // get the claim Id and then serve the asset + getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res); +}; + +module.exports = serverAssetByIdentifierAndClaim; diff --git a/server/routes/page/index.js b/server/routes/pages/index.js similarity index 100% rename from server/routes/page/index.js rename to server/routes/pages/index.js diff --git a/server/routes/page/redirect.js b/server/routes/pages/redirect.js similarity index 100% rename from server/routes/page/redirect.js rename to server/routes/pages/redirect.js diff --git a/server/routes/page/sendEmbedPage.js b/server/routes/pages/sendEmbedPage.js similarity index 100% rename from server/routes/page/sendEmbedPage.js rename to server/routes/pages/sendEmbedPage.js diff --git a/server/routes/page/sendReactApp.js b/server/routes/pages/sendReactApp.js similarity index 100% rename from server/routes/page/sendReactApp.js rename to server/routes/pages/sendReactApp.js diff --git a/server/server.js b/server/server.js new file mode 100644 index 00000000..a577536b --- /dev/null +++ b/server/server.js @@ -0,0 +1,98 @@ +// app dependencies +const express = require('express'); +const bodyParser = require('body-parser'); +const expressHandlebars = require('express-handlebars'); +const Handlebars = require('handlebars'); +const helmet = require('helmet'); +const passport = require('passport'); +const { serializeSpeechUser, deserializeSpeechUser } = require('./helpers/authHelpers.js'); +const cookieSession = require('cookie-session'); +const http = require('http'); +// logging dependencies +const logger = require('winston'); + +function Server () { + this.configureMysql = (mysqlConfig) => { + require('../config/mysqlConfig.js').configure(mysqlConfig); + }; + this.configureSite = (siteConfig) => { + require('../config/siteConfig.js').configure(siteConfig); + this.sessionKey = siteConfig.auth.sessionKey; + this.PORT = siteConfig.details.port; + }; + this.configureSlack = (slackConfig) => { + require('../config/slackConfig.js').configure(slackConfig); + }; + this.createApp = () => { + // create an Express application + const app = express(); + + // trust the proxy to get ip address for us + app.enable('trust proxy'); + + // add middleware + app.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties + app.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory + app.use(bodyParser.json()); // 'body parser' for parsing application/json + app.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded + app.use((req, res, next) => { // custom logging middleware to log all incoming http requests + logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`); + next(); + }); + + // configure passport + passport.serializeUser(serializeSpeechUser); + passport.deserializeUser(deserializeSpeechUser); + const localSignupStrategy = require('./passport/local-signup.js'); + const localLoginStrategy = require('./passport/local-login.js'); + passport.use('local-signup', localSignupStrategy); + passport.use('local-login', localLoginStrategy); + // initialize passport + app.use(cookieSession({ + name : 'session', + keys : [this.sessionKey], + maxAge: 24 * 60 * 60 * 1000, // i.e. 24 hours + })); + app.use(passport.initialize()); + app.use(passport.session()); + + // configure handlebars & register it with express app + const hbs = expressHandlebars.create({ + defaultLayout: 'embed', + handlebars : Handlebars, + }); + app.engine('handlebars', hbs.engine); + app.set('view engine', 'handlebars'); + + // set the routes on the app + require('./routes/auth.js')(app); + require('./routes/api.js')(app); + require('./routes/pages.js')(app); + require('./routes/assets.js')(app); + require('./routes/fallback.js')(app); + + this.app = app; + }; + this.initialize = () => { + require('./helpers/configureLogger.js')(logger); + require('./helpers/configureSlack.js')(logger); + this.createApp(); + this.server = http.Server(this.app); + }; + this.start = () => { + const db = require('./models/index'); + // sync sequelize + db.sequelize.sync() + // start the server + .then(() => { + this.server.listen(this.PORT, () => { + logger.info(`Server is listening on PORT ${this.PORT}`); + }); + }) + .catch((error) => { + logger.error(`Startup Error:`, error); + }); + }; +}; + +module.exports = Server; diff --git a/speech.js b/speech.js index aab99668..6a92d8d8 100644 --- a/speech.js +++ b/speech.js @@ -4,9 +4,9 @@ import rootSaga from 'sagas'; import GAListener from 'components/GAListener'; const api = require('./server/routes/api/'); -const asset = require('./server/routes/asset/'); +const asset = require('./server/routes/assets/'); const auth = require('./server/routes/auth/'); -const page = require('./server/routes/page/'); +const page = require('./server/routes/pages/'); const logger = require('./config/loggerConfig.js'); const mysql = require('./config/mysqlConfig'); const site = require('./config/siteConfig');