2017-06-19 22:10:06 +02:00
const logger = require ( 'winston' ) ;
2017-06-26 19:02:14 +02:00
const multipart = require ( 'connect-multiparty' ) ;
const multipartMiddleware = multipart ( ) ;
2017-06-26 19:43:35 +02:00
const publishController = require ( '../controllers/publishController.js' ) ;
const lbryApi = require ( '../helpers/libraries/lbryApi.js' ) ;
2017-06-26 19:02:14 +02:00
const publishHelpers = require ( '../helpers/libraries/publishHelpers.js' ) ;
2017-06-26 19:43:35 +02:00
const errorHandlers = require ( '../helpers/libraries/errorHandlers.js' ) ;
2017-06-30 07:26:29 +02:00
const { postToStats , sendGoogleAnalytics } = require ( '../controllers/statsController.js' ) ;
2017-05-24 20:07:43 +02:00
2017-06-17 22:51:30 +02:00
module . exports = app => {
// route to run a claim_list request on the daemon
2017-07-06 03:26:33 +02:00
app . get ( '/api/claim_list/:name' , ( { headers , ip , originalUrl , params } , res ) => {
2017-06-30 02:10:14 +02:00
// google analytics
2017-07-06 03:26:33 +02:00
sendGoogleAnalytics ( 'serve' , headers , ip , originalUrl ) ;
2017-06-30 02:10:14 +02:00
// log
2017-06-29 23:48:27 +02:00
logger . verbose ( ` GET request on ${ originalUrl } from ${ ip } ` ) ;
2017-06-30 02:10:14 +02:00
// serve the content
2017-06-17 22:51:30 +02:00
lbryApi
2017-07-03 23:48:35 +02:00
. getClaimsList ( params . name )
2017-06-17 22:51:30 +02:00
. then ( claimsList => {
2017-06-30 18:52:58 +02:00
postToStats ( 'serve' , originalUrl , ip , 'success' ) ;
2017-06-19 18:37:35 +02:00
res . status ( 200 ) . json ( claimsList ) ;
2017-06-17 22:51:30 +02:00
} )
. catch ( error => {
2017-06-28 07:41:48 +02:00
errorHandlers . handleRequestError ( 'publish' , originalUrl , ip , error , res ) ;
2017-06-19 18:37:35 +02:00
} ) ;
} ) ;
2017-07-03 23:48:35 +02:00
// route to check whether spee.ch has published to a claim
app . get ( '/api/isClaimAvailable/:name' , ( { ip , originalUrl , params } , res ) => {
// log
logger . verbose ( ` GET request on ${ originalUrl } from ${ ip } ` ) ;
// send response
publishController
. checkNameAvailability ( params . name )
. then ( result => {
2017-07-04 03:27:35 +02:00
if ( result === true ) {
2017-07-03 23:48:35 +02:00
res . status ( 200 ) . json ( true ) ;
2017-07-04 03:27:35 +02:00
} else {
logger . debug ( ` Rejecting publish request because ${ params . name } has already been published via spee.ch ` ) ;
res . status ( 200 ) . json ( false ) ;
2017-07-03 23:48:35 +02:00
}
} )
. catch ( error => {
res . status ( 500 ) . json ( error ) ;
} ) ;
} ) ;
2017-06-17 22:51:30 +02:00
// route to run a resolve request on the daemon
2017-07-06 03:26:33 +02:00
app . get ( '/api/resolve/:uri' , ( { headers , ip , originalUrl , params } , res ) => {
2017-06-30 02:10:14 +02:00
// google analytics
2017-07-06 03:26:33 +02:00
sendGoogleAnalytics ( 'serve' , headers , ip , originalUrl ) ;
2017-06-30 02:10:14 +02:00
// log
2017-06-29 23:48:27 +02:00
logger . verbose ( ` GET request on ${ originalUrl } from ${ ip } ` ) ;
2017-06-30 02:10:14 +02:00
// serve content
2017-06-17 22:51:30 +02:00
lbryApi
. resolveUri ( params . uri )
. then ( resolvedUri => {
2017-06-30 18:52:58 +02:00
postToStats ( 'serve' , originalUrl , ip , 'success' ) ;
2017-06-19 18:37:35 +02:00
res . status ( 200 ) . json ( resolvedUri ) ;
2017-06-17 22:51:30 +02:00
} )
. catch ( error => {
2017-06-28 07:41:48 +02:00
errorHandlers . handleRequestError ( 'publish' , originalUrl , ip , error , res ) ;
2017-06-19 18:37:35 +02:00
} ) ;
} ) ;
2017-06-26 19:02:14 +02:00
// route to run a publish request on the daemon
2017-07-06 03:26:33 +02:00
app . post ( '/api/publish' , multipartMiddleware , ( { body , files , headers , ip , originalUrl } , res ) => {
2017-06-30 02:10:14 +02:00
// google analytics
2017-07-06 03:26:33 +02:00
sendGoogleAnalytics ( 'publish' , headers , ip , originalUrl ) ;
2017-06-30 02:10:14 +02:00
// log
2017-06-29 23:48:27 +02:00
logger . verbose ( ` POST request on ${ originalUrl } from ${ ip } ` ) ;
2017-06-27 04:39:12 +02:00
// validate that a file was provided
2017-06-27 04:26:37 +02:00
const file = files . speech || files . null ;
2017-06-26 19:43:35 +02:00
if ( ! file ) {
2017-06-29 23:34:23 +02:00
postToStats ( 'publish' , originalUrl , ip , 'Error: file' ) ;
2017-06-27 04:26:37 +02:00
res . status ( 400 ) . send ( 'Error: No file was submitted or the key used was incorrect. Files posted through this route must use a key of "speech" or null' ) ;
2017-06-26 19:43:35 +02:00
return ;
}
2017-07-06 08:42:08 +02:00
// check if the size is provided (note: some clients may send incorrect content length or leave off content length)
logger . debug ( headers ) ;
if ( headers [ 'content-length' ] ) {
if ( headers [ 'content-length' ] > 5000000 ) {
res . status ( 400 ) . send ( 'Error: only files of 5 megabytes or less are allowed' ) ;
return ;
}
}
2017-06-27 04:26:37 +02:00
// validate name
const name = body . name || file . name . substring ( 0 , file . name . indexOf ( '.' ) ) ;
2017-07-03 20:36:51 +02:00
const invalidCharacters = /[^A-Za-z0-9,-]/ . exec ( name ) ;
2017-06-27 04:26:37 +02:00
if ( invalidCharacters ) {
2017-06-29 23:34:23 +02:00
postToStats ( 'publish' , originalUrl , ip , 'Error: name' ) ;
2017-06-27 04:26:37 +02:00
res . status ( 400 ) . send ( 'Error: The name you provided is not allowed. Please use A-Z, a-z, 0-9, "_" and "-" only.' ) ;
return ;
}
// validate license
2017-06-26 19:43:35 +02:00
const license = body . license || 'No License Provided' ;
2017-06-27 04:26:37 +02:00
if ( ( license . indexOf ( 'Public Domain' ) === - 1 ) && ( license . indexOf ( 'Creative Commons' ) === - 1 ) ) {
2017-06-29 23:34:23 +02:00
postToStats ( 'puplish' , originalUrl , ip , 'Error: license' ) ;
2017-06-27 04:26:37 +02:00
res . status ( 400 ) . send ( 'Error: Only posts with a license of "Public Domain" or "Creative Commons" are eligible for publishing through spee.ch' ) ;
return ;
}
2017-06-26 19:43:35 +02:00
const nsfw = body . nsfw || true ;
2017-06-27 04:26:37 +02:00
switch ( nsfw ) {
case true :
case false :
case 'true' :
case 'false' :
case 'on' :
case 'off' :
case 0 :
case '0' :
case 1 :
case '1' :
break ;
default :
2017-06-29 23:34:23 +02:00
postToStats ( 'publish' , originalUrl , ip , 'Error: nsfw' ) ;
2017-06-27 04:26:37 +02:00
res . status ( 400 ) . send ( 'Error: NSFW value was not accepted. NSFW must be set to either true, false, "on", or "off"' ) ;
return ;
}
2017-06-26 19:43:35 +02:00
const fileName = file . name ;
const filePath = file . path ;
const fileType = file . type ;
2017-06-26 19:02:14 +02:00
/ *
2017-06-27 04:39:12 +02:00
note : make sure it ' s not a harmful file type
2017-06-26 19:02:14 +02:00
* /
// prepare the publish parameters
const publishParams = publishHelpers . createPublishParams ( name , filePath , license , nsfw ) ;
// publish the file
publishController
. publish ( publishParams , fileName , fileType )
. then ( result => {
2017-06-29 23:34:23 +02:00
postToStats ( 'publish' , originalUrl , ip , 'success' ) ;
2017-06-26 19:02:14 +02:00
res . status ( 200 ) . json ( result ) ;
} )
. catch ( error => {
2017-06-28 07:41:48 +02:00
errorHandlers . handleRequestError ( 'publish' , originalUrl , ip , error , res ) ;
2017-06-26 19:02:14 +02:00
} ) ;
} ) ;
2017-06-19 18:37:35 +02:00
} ;