2024-07-18 21:35:17 +03:00
import log from "../services/log.js" ;
import fileService from "./api/files.js" ;
import scriptService from "../services/script.js" ;
import cls from "../services/cls.js" ;
import sql from "../services/sql.js" ;
import becca from "../becca/becca.js" ;
2025-01-09 18:07:02 +02:00
import { Request , Response , Router } from "express" ;
2024-04-07 14:05:50 +03:00
function handleRequest ( req : Request , res : Response ) {
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
2024-04-07 14:05:50 +03:00
const attributeIds = sql . getColumn < string > ( "SELECT attributeId FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')" ) ;
2021-05-02 19:59:16 +02:00
2025-01-09 18:07:02 +02:00
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 ) {
2024-04-07 14:05:50 +03:00
if ( ! attr ? . value . trim ( ) ) {
2020-11-06 21:52:57 +01:00
continue ;
}
2023-04-22 19:37:49 +08:00
const regex = new RegExp ( ` ^ ${ attr . value } $ ` ) ;
2020-06-22 23:13:53 +02:00
let match ;
2019-01-27 12:28:20 +01:00
2020-06-22 23:13:53 +02:00
try {
match = path . match ( regex ) ;
2025-01-09 18:07:02 +02:00
} catch ( e : any ) {
2023-05-03 10:23:20 +02:00
log . error ( ` Testing path for label ' ${ attr . attributeId } ', regex ' ${ attr . value } ' failed with error: ${ e . message } , stack: ${ e . stack } ` ) ;
2020-06-22 23:13:53 +02:00
continue ;
}
if ( ! match ) {
continue ;
}
2019-01-27 15:47:40 +01:00
2025-01-09 18:07:02 +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
2023-05-03 10:23:20 +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
} ) ;
2025-01-09 18:07:02 +02:00
} catch ( e : any ) {
2023-05-03 10:23:20 +02:00
log . error ( ` Custom handler ' ${ note . noteId } ' failed with: ${ e . message } , ${ e . stack } ` ) ;
2019-01-27 16:37:18 +01:00
2025-01-09 18:07:02 +02:00
res . setHeader ( "Content-Type" , "text/plain" ) . status ( 500 ) . send ( e . message ) ;
2019-01-27 16:37:18 +01:00
}
2025-01-09 18:07:02 +02:00
} else if ( attr . name === "customResourceProvider" ) {
2023-05-03 10:23:20 +02:00
fileService . downloadNoteInt ( attr . noteId , res ) ;
2025-01-09 18:07:02 +02:00
} else {
2023-05-03 10:23:20 +02:00
throw new Error ( ` Unrecognized attribute name ' ${ attr . name } ' ` ) ;
2020-06-22 23:13:53 +02:00
}
2019-01-27 16:37:18 +01:00
2023-05-05 23:41:11 +02:00
return ; // only the first handler is executed
2020-06-22 23:13:53 +02:00
}
2019-01-27 16:37:18 +01:00
2023-05-03 10:23:20 +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 ) ;
2025-01-09 18:07:02 +02:00
res . setHeader ( "Content-Type" , "text/plain" ) . status ( 404 ) . send ( message ) ;
2020-06-22 23:13:53 +02:00
}
2019-01-27 16:37:18 +01:00
2024-04-07 14:05:50 +03:00
function register ( router : Router ) {
2020-06-22 23:13:53 +02:00
// explicitly no CSRF middleware since it's meant to allow integration from external services
2019-01-27 12:28:20 +01:00
2025-01-09 18:07:02 +02:00
router . all ( "/custom/:path*" , ( req : Request , res : Response , 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
} ) ;
}
2024-07-18 21:42:44 +03:00
export default {
2019-01-27 12:28:20 +01:00
register
2020-06-20 12:31:38 +02:00
} ;