2019-01-27 12:28:20 +01:00
const log = require ( '../services/log' ) ;
2019-11-09 11:58:52 +01:00
const fileUploadService = require ( './api/files.js' ) ;
2019-01-27 12:28:20 +01:00
const scriptService = require ( '../services/script' ) ;
2020-06-22 23:13:53 +02:00
const cls = require ( '../services/cls' ) ;
2021-05-02 19:59:16 +02:00
const sql = require ( "../services/sql" ) ;
2021-05-17 22:09:49 +02:00
const becca = require ( "../becca/becca.js" ) ;
2019-01-27 12:28:20 +01:00
2021-05-15 22:57:23 +02:00
function handleRequest ( req , res ) {
2020-06-22 23:13:53 +02:00
// express puts content after first slash into 0 index element
2019-03-24 22:41:53 +01:00
2020-06-22 23:13:53 +02:00
const path = req . params . path + req . params [ 0 ] ;
2019-03-24 22:41:53 +01:00
2021-05-02 19:59:16 +02:00
const attributeIds = sql . getColumn ( "SELECT attributeId FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')" ) ;
const attrs = attributeIds . map ( attrId => becca . getAttribute ( attrId ) ) ;
2019-01-27 15:47:40 +01:00
2020-06-22 23:13:53 +02:00
for ( const attr of attrs ) {
2020-11-06 21:52:57 +01:00
if ( ! attr . value . trim ( ) ) {
continue ;
}
2020-06-22 23:13:53 +02:00
const regex = new RegExp ( attr . value ) ;
let match ;
2019-01-27 12:28:20 +01:00
2020-06-22 23:13:53 +02:00
try {
match = path . match ( regex ) ;
}
catch ( e ) {
log . error ( ` Testing path for label ${ attr . attributeId } , regex= ${ attr . value } failed with error ` + e . stack ) ;
continue ;
}
if ( ! match ) {
continue ;
}
2019-01-27 15:47:40 +01:00
2020-06-22 23:13:53 +02:00
if ( attr . name === 'customRequestHandler' ) {
2020-06-24 22:08:31 +02:00
const note = attr . getNote ( ) ;
2019-01-27 12:28:20 +01:00
2020-06-22 23:13:53 +02:00
log . info ( ` Handling custom request " ${ path } " with note ${ note . noteId } ` ) ;
2019-01-27 12:28:20 +01:00
try {
2020-06-24 22:08:31 +02:00
scriptService . executeNote ( note , {
2020-06-22 23:13:53 +02:00
pathParams : match . slice ( 1 ) ,
req ,
res
} ) ;
2019-01-27 12:28:20 +01:00
}
catch ( e ) {
2020-06-22 23:13:53 +02:00
log . error ( ` Custom handler ${ note . noteId } failed with ${ e . message } ` ) ;
2019-01-27 16:37:18 +01:00
2020-06-22 23:13:53 +02:00
res . status ( 500 ) . send ( e . message ) ;
2019-01-27 16:37:18 +01:00
}
2020-06-22 23:13:53 +02:00
}
else if ( attr . name === 'customResourceProvider' ) {
2020-06-24 22:08:31 +02:00
fileUploadService . downloadNoteFile ( attr . noteId , res ) ;
2020-06-22 23:13:53 +02:00
}
else {
throw new Error ( "Unrecognized attribute name " + attr . name ) ;
}
2019-01-27 16:37:18 +01:00
2020-06-22 23:13:53 +02:00
return ; // only first handler is executed
}
2019-01-27 16:37:18 +01:00
2020-06-22 23:13:53 +02:00
const message = ` No handler matched for custom ${ path } request. ` ;
2019-02-03 11:15:32 +01:00
2020-06-22 23:13:53 +02:00
log . info ( message ) ;
res . status ( 404 ) . send ( message ) ;
}
2019-01-27 16:37:18 +01:00
2020-06-22 23:13:53 +02:00
function register ( router ) {
// explicitly no CSRF middleware since it's meant to allow integration from external services
2019-01-27 12:28:20 +01:00
2021-05-15 22:57:23 +02:00
router . all ( '/custom/:path*' , ( req , res , next ) => {
2020-06-22 23:13:53 +02:00
cls . namespace . bindEmitter ( req ) ;
cls . namespace . bindEmitter ( res ) ;
2019-01-27 15:47:40 +01:00
2020-06-22 23:13:53 +02:00
cls . init ( ( ) => handleRequest ( req , res ) ) ;
2019-01-27 12:28:20 +01:00
} ) ;
}
module . exports = {
register
2020-06-20 12:31:38 +02:00
} ;