From 74a78020883d97dd3b55b6dc832e6dd67013dce0 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 22 Jun 2020 23:13:53 +0200 Subject: [PATCH] fix custom resource handler, closes #1125 --- src/routes/custom.js | 115 +++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/src/routes/custom.js b/src/routes/custom.js index 7527b94b2..c8535c604 100644 --- a/src/routes/custom.js +++ b/src/routes/custom.js @@ -2,67 +2,76 @@ const repository = require('../services/repository'); const log = require('../services/log'); const fileUploadService = require('./api/files.js'); const scriptService = require('../services/script'); +const cls = require('../services/cls'); + +async function handleRequest(req, res) { + // express puts content after first slash into 0 index element + + const path = req.params.path + req.params[0]; + + const attrs = await repository.getEntities("SELECT * FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')"); + + for (const attr of attrs) { + const regex = new RegExp(attr.value); + let match; + + 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; + } + + if (attr.name === 'customRequestHandler') { + const note = await attr.getNote(); + + log.info(`Handling custom request "${path}" with note ${note.noteId}`); + + try { + await scriptService.executeNote(note, { + pathParams: match.slice(1), + req, + res + }); + } + catch (e) { + log.error(`Custom handler ${note.noteId} failed with ${e.message}`); + + res.status(500).send(e.message); + } + } + else if (attr.name === 'customResourceProvider') { + await fileUploadService.downloadNoteFile(attr.noteId, res); + } + else { + throw new Error("Unrecognized attribute name " + attr.name); + } + + return; // only first handler is executed + } + + const message = `No handler matched for custom ${path} request.`; + + log.info(message); + res.status(404).send(message); +} function register(router) { // explicitly no CSRF middleware since it's meant to allow integration from external services router.all('/custom/:path*', async (req, res, next) => { - // express puts content after first slash into 0 index element - const path = req.params.path + req.params[0]; + cls.namespace.bindEmitter(req); + cls.namespace.bindEmitter(res); - const attrs = await repository.getEntities("SELECT * FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')"); - - for (const attr of attrs) { - const regex = new RegExp(attr.value); - let match; - - 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; - } - - if (attr.name === 'customRequestHandler') { - const note = await attr.getNote(); - - log.info(`Handling custom request "${path}" with note ${note.noteId}`); - - try { - await scriptService.executeNote(note, { - pathParams: match.slice(1), - req, - res - }); - } - catch (e) { - log.error(`Custom handler ${note.noteId} failed with ${e.message}`); - - res.status(500).send(e.message); - } - } - else if (attr.name === 'customResourceProvider') { - await fileUploadService.downloadNoteFile(attr.noteId, res); - } - else { - throw new Error("Unrecognized attribute name " + attr.name); - } - - return; // only first handler is executed - } - - const message = `No handler matched for custom ${path} request.`; - - log.info(message); - res.status(404).send(message); + cls.init(() => handleRequest(req, res)); }); } module.exports = { register -}; \ No newline at end of file +};