2020-09-02 17:16:02 -04:00
const assert = require ( 'assert' ) . strict ;
2020-11-23 13:24:19 -05:00
const hasPadAccess = require ( '../../padaccess' ) ;
const settings = require ( '../../utils/Settings' ) ;
const exportHandler = require ( '../../handler/ExportHandler' ) ;
const importHandler = require ( '../../handler/ImportHandler' ) ;
const padManager = require ( '../../db/PadManager' ) ;
const readOnlyManager = require ( '../../db/ReadOnlyManager' ) ;
const authorManager = require ( '../../db/AuthorManager' ) ;
const rateLimit = require ( 'express-rate-limit' ) ;
const securityManager = require ( '../../db/SecurityManager' ) ;
const webaccess = require ( './webaccess' ) ;
2020-04-04 20:39:33 +00:00
2020-11-23 13:24:19 -05:00
settings . importExportRateLimiting . onLimitReached = function ( req , res , options ) {
2020-04-04 20:39:33 +00:00
// when the rate limiter triggers, write a warning in the logs
console . warn ( ` Import/Export rate limiter triggered on " ${ req . originalUrl } " for IP address ${ req . ip } ` ) ;
2020-11-23 13:24:19 -05:00
} ;
2020-04-04 20:39:33 +00:00
2020-11-23 13:24:19 -05:00
const limiter = rateLimit ( settings . importExportRateLimiting ) ;
2012-02-25 16:06:08 +01:00
exports . expressCreateServer = function ( hook _name , args , cb ) {
2020-04-13 01:33:43 +02:00
// handle export requests
2020-04-04 20:39:33 +00:00
args . app . use ( '/p/:pad/:rev?/export/:type' , limiter ) ;
2020-11-23 13:24:19 -05:00
args . app . get ( '/p/:pad/:rev?/export/:type' , async ( req , res , next ) => {
const types = [ 'pdf' , 'doc' , 'txt' , 'html' , 'odt' , 'etherpad' ] ;
// send a 404 if we don't support this filetype
2012-02-25 16:06:08 +01:00
if ( types . indexOf ( req . params . type ) == - 1 ) {
2019-01-23 16:29:36 +00:00
return next ( ) ;
2012-02-25 16:06:08 +01:00
}
2019-02-08 23:20:57 +01:00
// if abiword is disabled, and this is a format we only support with abiword, output a message
2020-11-23 13:24:19 -05:00
if ( settings . exportAvailable ( ) == 'no' &&
[ 'odt' , 'pdf' , 'doc' ] . indexOf ( req . params . type ) !== - 1 ) {
2020-04-13 01:33:43 +02:00
console . error ( ` Impossible to export pad " ${ req . params . pad } " in ${ req . params . type } format. There is no converter configured ` ) ;
// ACHTUNG: do not include req.params.type in res.send() because there is no HTML escaping and it would lead to an XSS
2020-11-23 13:24:19 -05:00
res . send ( 'This export is not enabled at this Etherpad instance. Set the path to Abiword or soffice (LibreOffice) in settings.json to enable this feature' ) ;
2012-02-25 16:06:08 +01:00
return ;
}
2020-11-23 13:24:19 -05:00
res . header ( 'Access-Control-Allow-Origin' , '*' ) ;
2012-02-25 16:06:08 +01:00
2019-01-23 16:29:36 +00:00
if ( await hasPadAccess ( req , res ) ) {
2020-09-16 14:57:27 -03:00
let padId = req . params . pad ;
let readOnlyId = null ;
if ( readOnlyManager . isReadOnlyId ( padId ) ) {
readOnlyId = padId ;
padId = await readOnlyManager . getPadId ( readOnlyId ) ;
}
2020-11-23 13:24:19 -05:00
const exists = await padManager . doesPadExists ( padId ) ;
2019-01-23 16:29:36 +00:00
if ( ! exists ) {
2020-09-16 14:57:27 -03:00
console . warn ( ` Someone tried to export a pad that doesn't exist ( ${ padId } ) ` ) ;
2019-01-23 16:29:36 +00:00
return next ( ) ;
}
2018-04-04 21:48:32 +01:00
2020-04-13 01:33:43 +02:00
console . log ( ` Exporting pad " ${ req . params . pad } " in ${ req . params . type } format ` ) ;
2020-09-16 14:57:27 -03:00
exportHandler . doExport ( req , res , padId , readOnlyId , req . params . type ) ;
2019-01-23 16:29:36 +00:00
}
2012-02-25 16:06:08 +01:00
} ) ;
2019-02-08 23:20:57 +01:00
// handle import requests
2020-04-04 20:39:33 +00:00
args . app . use ( '/p/:pad/import' , limiter ) ;
2020-11-23 13:24:19 -05:00
args . app . post ( '/p/:pad/import' , async ( req , res , next ) => {
2020-09-11 17:12:29 -04:00
const { session : { user } = { } } = req ;
2020-10-01 15:49:04 -04:00
const { accessStatus } = await securityManager . checkAccess (
2020-10-07 13:43:54 +01:00
req . params . pad , req . cookies . sessionID , req . cookies . token , user ) ;
2020-10-01 15:49:04 -04:00
if ( accessStatus !== 'grant' || ! webaccess . userCanModify ( req . params . pad , req ) ) {
return res . status ( 403 ) . send ( 'Forbidden' ) ;
2019-01-23 16:29:36 +00:00
}
2020-10-01 15:49:04 -04:00
await importHandler . doImport ( req , res , req . params . pad ) ;
2012-02-25 16:06:08 +01:00
} ) ;
2020-10-10 22:51:26 -04:00
return cb ( ) ;
2020-11-23 13:24:19 -05:00
} ;