@tiledesk/tiledesk-server 2.25.0 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,9 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.26.0
9
+ - Added pubmodules proxy route for docsparse
10
+
8
11
  # 2.25.0
9
12
  - Added support for OpenRouter
10
13
  - Added support for Gemini Agent Platform
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-server",
3
3
  "description": "The Tiledesk server module",
4
- "version": "2.25.0",
4
+ "version": "2.26.0",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -0,0 +1,94 @@
1
+ var express = require('express');
2
+ var router = express.Router({ mergeParams: true });
3
+ var axios = require('axios');
4
+ var querystring = require('querystring');
5
+ var winston = require('../../config/winston');
6
+
7
+ // Headers that must not be forwarded between the two connections
8
+ const HOP_BY_HOP_HEADERS = [
9
+ 'connection',
10
+ 'keep-alive',
11
+ 'proxy-authenticate',
12
+ 'proxy-authorization',
13
+ 'te',
14
+ 'trailer',
15
+ 'transfer-encoding',
16
+ 'upgrade'
17
+ ];
18
+
19
+ function forwardableRequestHeaders(req) {
20
+ let headers = Object.assign({}, req.headers);
21
+ HOP_BY_HOP_HEADERS.forEach((header) => {
22
+ delete headers[header];
23
+ });
24
+ delete headers['host'];
25
+ delete headers['content-length'];
26
+ return headers;
27
+ }
28
+
29
+ function requestBody(req, headers) {
30
+ // A request without content-length nor transfer-encoding has no body at all
31
+ if (req.headers['content-length'] === undefined && req.headers['transfer-encoding'] === undefined) {
32
+ return undefined;
33
+ }
34
+
35
+ // body-parser sets _body when it already consumed the stream (json / urlencoded),
36
+ // in that case the parsed body must be serialized again
37
+ if (req._body) {
38
+ let contentType = req.headers['content-type'] || '';
39
+ if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {
40
+ return querystring.stringify(req.body);
41
+ }
42
+ return req.body;
43
+ }
44
+
45
+ // Everything else (multipart, binary, ...) is piped as it is
46
+ return req;
47
+ }
48
+
49
+ router.use(function (req, res) {
50
+
51
+ let baseUrl = process.env.DOCSPARSE_BASEURL;
52
+
53
+ if (!baseUrl) {
54
+ winston.error("DOCSPARSE_BASEURL is not set. Unable to forward the request to docsparse");
55
+ return res.status(503).send({ success: false, msg: "Docsparse module is not configured. Set the DOCSPARSE_BASEURL environment variable" });
56
+ }
57
+
58
+ // req.url is the part of the url following the module route, query string included
59
+ let url = baseUrl.replace(/\/+$/, '') + req.url;
60
+ let headers = forwardableRequestHeaders(req);
61
+
62
+ winston.debug("[DOCSPARSE] " + req.method + " " + url);
63
+
64
+ axios({
65
+ url: url,
66
+ method: req.method,
67
+ headers: headers,
68
+ data: requestBody(req, headers),
69
+ responseType: 'stream',
70
+ decompress: false,
71
+ maxContentLength: Infinity,
72
+ maxBodyLength: Infinity,
73
+ validateStatus: () => true
74
+ }).then((response) => {
75
+
76
+ winston.debug("[DOCSPARSE] response status " + response.status + " for " + url);
77
+
78
+ Object.keys(response.headers).forEach((header) => {
79
+ if (HOP_BY_HOP_HEADERS.indexOf(header.toLowerCase()) === -1) {
80
+ res.setHeader(header, response.headers[header]);
81
+ }
82
+ });
83
+
84
+ res.status(response.status);
85
+ response.data.pipe(res);
86
+
87
+ }).catch((err) => {
88
+ winston.error("[DOCSPARSE] Error forwarding the request to " + url + ": " + err.message);
89
+ res.status(502).send({ success: false, msg: "Error forwarding the request to docsparse", error: err.message });
90
+ })
91
+
92
+ });
93
+
94
+ module.exports = router;
@@ -0,0 +1,3 @@
1
+ const docsparseRoute = require("./docsparseRoute");
2
+
3
+ module.exports = { docsparseRoute: docsparseRoute }
@@ -76,6 +76,9 @@ class PubModulesManager {
76
76
  this.dialogFlow = undefined;
77
77
 
78
78
  this.analyticsPublisher = undefined;
79
+
80
+ this.docsparse = undefined;
81
+ this.docsparseRoute = undefined;
79
82
  }
80
83
 
81
84
 
@@ -170,6 +173,12 @@ class PubModulesManager {
170
173
  winston.info("ModulesManager trigger controller loaded");
171
174
  }
172
175
 
176
+ if (this.docsparseRoute) {
177
+ // docsparse apis have no authentication on their own: the server authenticates the caller before forwarding
178
+ app.use('/:projectid/docsparse', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('admin', ['bot','subscription'])], this.docsparseRoute);
179
+ winston.info("ModulesManager docsparse controller loaded");
180
+ }
181
+
173
182
  }
174
183
 
175
184
 
@@ -609,6 +618,21 @@ class PubModulesManager {
609
618
  winston.info("PubModulesManager error initializing analyticsPublisher module", err);
610
619
  }
611
620
  }
621
+
622
+ try {
623
+ this.docsparse = require('./docsparse');
624
+ winston.debug("this.docsparse: " + this.docsparse);
625
+
626
+ this.docsparseRoute = this.docsparse.docsparseRoute;
627
+
628
+ winston.info("PubModulesManager initialized docsparse.");
629
+ } catch(err) {
630
+ if (err.code == 'MODULE_NOT_FOUND') {
631
+ winston.info("PubModulesManager init docsparse module not found");
632
+ } else {
633
+ winston.info("PubModulesManager error initializing docsparse module", err);
634
+ }
635
+ }
612
636
  }
613
637
 
614
638
  start() {