@tiledesk/tiledesk-server 2.9.31 → 2.9.33
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +13 -0
- package/config/labels/widget.json +15 -0
- package/deploy.sh +1 -1
- package/models/kb_setting.js +53 -1
- package/package.json +3 -3
- package/routes/kb.js +205 -35
- package/routes/project.js +108 -1
- package/routes/request.js +85 -94
- package/services/openaiService.js +6 -2
- package/test/kbRoute.js +319 -37
- package/test/projectRoute.js +41 -0
package/routes/kb.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
var express = require('express');
|
2
|
-
var { Namespace } = require('../models/kb_setting');
|
3
|
-
var { KB } = require('../models/kb_setting');
|
2
|
+
var { Namespace, KB, Engine } = require('../models/kb_setting');
|
3
|
+
// var { KB } = require('../models/kb_setting');
|
4
|
+
// var { Engine } = require('../models/kb_setting')
|
4
5
|
var router = express.Router();
|
5
6
|
var winston = require('../config/winston');
|
6
7
|
var multer = require('multer')
|
@@ -17,6 +18,7 @@ let Integration = require('../models/integrations');
|
|
17
18
|
var parsecsv = require("fast-csv");
|
18
19
|
|
19
20
|
const { MODELS_MULTIPLIER } = require('../utils/aiUtils');
|
21
|
+
const { body } = require('express-validator');
|
20
22
|
|
21
23
|
const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
|
22
24
|
const JOB_TOPIC_EXCHANGE = process.env.JOB_TOPIC_EXCHANGE_TRAIN || 'tiledesk-trainer';
|
@@ -45,6 +47,13 @@ let default_preview_settings = {
|
|
45
47
|
//context: "You are an awesome AI Assistant."
|
46
48
|
context: null
|
47
49
|
}
|
50
|
+
let default_engine = {
|
51
|
+
name: "pinecone",
|
52
|
+
type: "pod",
|
53
|
+
apikey: "",
|
54
|
+
vector_size: 1536,
|
55
|
+
index_name: process.env.PINECONE_INDEX
|
56
|
+
}
|
48
57
|
|
49
58
|
//let default_context = "Answer if and ONLY if the answer is contained in the context provided. If the answer is not contained in the context provided ALWAYS answer with <NOANS>\n{context}"
|
50
59
|
//let default_context = "You are an helpful assistant for question-answering tasks.\nUse ONLY the following pieces of retrieved context to answer the question.\nIf you don't know the answer, just say that you don't know.\nIf none of the retrieved context answer the question, add this word to the end <NOANS>\n\n{context}";
|
@@ -68,9 +77,9 @@ router.post('/scrape/single', async (req, res) => {
|
|
68
77
|
let data = req.body;
|
69
78
|
winston.debug("/scrape/single data: ", data);
|
70
79
|
|
71
|
-
if (!data.scrape_type) {
|
72
|
-
|
73
|
-
}
|
80
|
+
// if (!data.scrape_type) {
|
81
|
+
// data.scrape_type = 1;
|
82
|
+
// }
|
74
83
|
|
75
84
|
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
76
85
|
winston.error("find namespaces error: ", err)
|
@@ -112,11 +121,28 @@ router.post('/scrape/single', async (req, res) => {
|
|
112
121
|
json.content = kb.content;
|
113
122
|
}
|
114
123
|
|
115
|
-
json.scrape_type = 1;
|
116
|
-
if (data.scrape_type) {
|
117
|
-
|
124
|
+
// json.scrape_type = 1;
|
125
|
+
// if (data.scrape_type) {
|
126
|
+
// json.scrape_type = data.scrape_type;
|
127
|
+
// }
|
128
|
+
|
129
|
+
if (kb.scrape_type) {
|
130
|
+
json.scrape_type = kb.scrape_type
|
118
131
|
}
|
119
132
|
|
133
|
+
if (kb.scrape_options) {
|
134
|
+
json.parameters_scrape_type_4 = {
|
135
|
+
tags_to_extract: kb.scrape_options.tags_to_extract,
|
136
|
+
unwanted_tags: kb.scrape_options.unwanted_tags,
|
137
|
+
unwanted_classnames: kb.scrape_options.unwanted_classnames
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
let ns = namespaces.find(n => n.id === kb.namespace);
|
142
|
+
json.engine = ns.engine || default_engine;
|
143
|
+
|
144
|
+
winston.verbose("/scrape/single json: ", json);
|
145
|
+
|
120
146
|
startScrape(json).then((response) => {
|
121
147
|
winston.verbose("startScrape response: ", response);
|
122
148
|
res.status(200).send(response);
|
@@ -132,6 +158,8 @@ router.post('/scrape/single', async (req, res) => {
|
|
132
158
|
|
133
159
|
router.post('/scrape/status', async (req, res) => {
|
134
160
|
|
161
|
+
let project_id = req.projectid;
|
162
|
+
// (EXAMPLE) body: { id, namespace }
|
135
163
|
let data = req.body;
|
136
164
|
winston.debug("/scrapeStatus req.body: ", req.body);
|
137
165
|
|
@@ -143,6 +171,25 @@ router.post('/scrape/status', async (req, res) => {
|
|
143
171
|
returnObject = true;
|
144
172
|
}
|
145
173
|
|
174
|
+
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
175
|
+
winston.error("find namespaces error: ", err)
|
176
|
+
res.status(500).send({ success: false, error: err })
|
177
|
+
})
|
178
|
+
|
179
|
+
if (!namespaces || namespaces.length == 0) {
|
180
|
+
let alert = "No namespace found for the selected project " + project_id + ". Cannot add content to a non-existent namespace."
|
181
|
+
winston.warn(alert);
|
182
|
+
res.status(403).send(alert);
|
183
|
+
}
|
184
|
+
|
185
|
+
let namespaceIds = namespaces.map(namespace => namespace.id);
|
186
|
+
if (!namespaceIds.includes(data.namespace)) {
|
187
|
+
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
188
|
+
}
|
189
|
+
|
190
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
191
|
+
data.engine = ns.engine || default_engine;
|
192
|
+
|
146
193
|
openaiService.scrapeStatus(data).then(async (response) => {
|
147
194
|
|
148
195
|
winston.debug("scrapeStatus response.data: ", response.data);
|
@@ -229,7 +276,7 @@ router.post('/qa', async (req, res) => {
|
|
229
276
|
}
|
230
277
|
|
231
278
|
// Check if "Advanced Mode" is active. In such case the default_context must be not appended
|
232
|
-
if (!data.
|
279
|
+
if (!data.advancedPrompt) {
|
233
280
|
if (data.system_context) {
|
234
281
|
data.system_context = data.system_context + " \n" + contexts[data.model];
|
235
282
|
} else {
|
@@ -237,9 +284,15 @@ router.post('/qa', async (req, res) => {
|
|
237
284
|
}
|
238
285
|
}
|
239
286
|
|
240
|
-
|
241
|
-
|
242
|
-
|
287
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
288
|
+
data.engine = ns.engine || default_engine;
|
289
|
+
|
290
|
+
delete data.advancedPrompt;
|
291
|
+
winston.verbose("ask data: ", data);
|
292
|
+
|
293
|
+
if (process.env.NODE_ENV === 'test') {
|
294
|
+
return res.status(200).send({ success: true, message: "Question skipped in test environment"});
|
295
|
+
}
|
243
296
|
|
244
297
|
openaiService.askNamespace(data).then((resp) => {
|
245
298
|
winston.debug("qa resp: ", resp.data);
|
@@ -317,6 +370,9 @@ router.delete('/delete', async (req, res) => {
|
|
317
370
|
if (!namespaceIds.includes(data.namespace)) {
|
318
371
|
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
319
372
|
}
|
373
|
+
|
374
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
375
|
+
data.engine = ns.engine || default_engine;
|
320
376
|
|
321
377
|
openaiService.deleteIndex(data).then((resp) => {
|
322
378
|
winston.debug("delete resp: ", resp.data);
|
@@ -352,6 +408,11 @@ router.delete('/deleteall', async (req, res) => {
|
|
352
408
|
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
353
409
|
}
|
354
410
|
|
411
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
412
|
+
data.engine = ns.engine || default_engine;
|
413
|
+
|
414
|
+
winston.verbose("/deleteall data: ", data);
|
415
|
+
|
355
416
|
openaiService.deleteNamespace(data).then((resp) => {
|
356
417
|
winston.debug("delete namespace resp: ", resp.data);
|
357
418
|
res.status(200).send(resp.data);
|
@@ -394,7 +455,8 @@ router.get('/namespace/all', async (req, res) => {
|
|
394
455
|
id: project_id,
|
395
456
|
name: "Default",
|
396
457
|
preview_settings: default_preview_settings,
|
397
|
-
default: true
|
458
|
+
default: true,
|
459
|
+
engine: default_engine
|
398
460
|
})
|
399
461
|
|
400
462
|
new_namespace.save((err, savedNamespace) => {
|
@@ -448,7 +510,11 @@ router.get('/namespace/:id/chunks/:content_id', async (req, res) => {
|
|
448
510
|
return res.status(403).send({ success: false, error: "Not allowed. The conten does not belong to the current namespace." })
|
449
511
|
}
|
450
512
|
|
451
|
-
|
513
|
+
let ns = namespaces.find(n => n.id === namespace_id);
|
514
|
+
let engine = ns.engine || default_engine;
|
515
|
+
delete engine._id;
|
516
|
+
|
517
|
+
openaiService.getContentChunks(namespace_id, content_id, engine).then((resp) => {
|
452
518
|
let chunks = resp.data;
|
453
519
|
winston.debug("chunks for content " + content_id);
|
454
520
|
winston.debug("chunks found ", chunks);
|
@@ -492,7 +558,6 @@ router.get('/namespace/:id/chatbots', async (req, res) => {
|
|
492
558
|
let chatbots = intents.map(i => i.id_faq_kb);
|
493
559
|
let uniqueChatbots = [...new Set(chatbots)];
|
494
560
|
|
495
|
-
|
496
561
|
let chatbotPromises = uniqueChatbots.map(async (c_id) => {
|
497
562
|
try {
|
498
563
|
let chatbot = await faq_kb.findOne({ _id: c_id, trashed: false });
|
@@ -527,6 +592,7 @@ router.post('/namespace', async (req, res) => {
|
|
527
592
|
id: namespace_id,
|
528
593
|
name: body.name,
|
529
594
|
preview_settings: default_preview_settings,
|
595
|
+
engine: default_engine
|
530
596
|
})
|
531
597
|
|
532
598
|
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
@@ -589,11 +655,23 @@ router.put('/namespace/:id', async (req, res) => {
|
|
589
655
|
|
590
656
|
router.delete('/namespace/:id', async (req, res) => {
|
591
657
|
|
592
|
-
let
|
658
|
+
let project_id = req.projectid;
|
593
659
|
let namespace_id = req.params.id;
|
594
660
|
|
661
|
+
let namespace = await Namespace.findOne({ id_project: project_id, id: namespace_id }).catch((err) => {
|
662
|
+
winston.error("find namespace error: ", err);
|
663
|
+
res.status(500).send({ success: false, error: err });
|
664
|
+
})
|
665
|
+
|
666
|
+
if (!namespace) {
|
667
|
+
let alert = "No namespace found for id " + namespace_id;
|
668
|
+
winston.warn(alert);
|
669
|
+
res.status(404).send({ success: false, error: alert })
|
670
|
+
}
|
671
|
+
|
595
672
|
let data = {
|
596
|
-
namespace: namespace_id
|
673
|
+
namespace: namespace_id,
|
674
|
+
engine: namespace.engine || default_engine
|
597
675
|
}
|
598
676
|
|
599
677
|
if (req.query.contents_only && (req.query.contents_only === true || req.query.contents_only === 'true')) {
|
@@ -601,7 +679,7 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
601
679
|
openaiService.deleteNamespace(data).then(async (resp) => {
|
602
680
|
winston.debug("delete namespace resp: ", resp.data);
|
603
681
|
|
604
|
-
let deleteResponse = await KB.deleteMany({ id_project:
|
682
|
+
let deleteResponse = await KB.deleteMany({ id_project: project_id, namespace: namespace_id }).catch((err) => {
|
605
683
|
winston.error("deleteMany error: ", err);
|
606
684
|
return res.status(500).send({ success: false, error: err });
|
607
685
|
})
|
@@ -635,7 +713,7 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
635
713
|
openaiService.deleteNamespace(data).then(async (resp) => {
|
636
714
|
winston.debug("delete namespace resp: ", resp.data);
|
637
715
|
|
638
|
-
let deleteResponse = await KB.deleteMany({ id_project:
|
716
|
+
let deleteResponse = await KB.deleteMany({ id_project: project_id, namespace: namespace_id }).catch((err) => {
|
639
717
|
winston.error("deleteMany error: ", err);
|
640
718
|
return res.status(500).send({ success: false, error: err });
|
641
719
|
})
|
@@ -831,7 +909,7 @@ router.post('/', async (req, res) => {
|
|
831
909
|
if (!namespaceIds.includes(body.namespace)) {
|
832
910
|
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
833
911
|
}
|
834
|
-
|
912
|
+
|
835
913
|
let quoteManager = req.app.get('quote_manager');
|
836
914
|
let limits = await quoteManager.getPlanLimits(req.project);
|
837
915
|
let kbs_limit = limits.kbs;
|
@@ -848,6 +926,7 @@ router.post('/', async (req, res) => {
|
|
848
926
|
if (total_count > kbs_limit) {
|
849
927
|
return res.status(403).send({ success: false, error: "Cannot exceed the number of resources in the current plan", plan_limit: kbs_limit })
|
850
928
|
}
|
929
|
+
|
851
930
|
let new_kb = {
|
852
931
|
id_project: project_id,
|
853
932
|
name: body.name,
|
@@ -860,6 +939,19 @@ router.post('/', async (req, res) => {
|
|
860
939
|
if (!new_kb.namespace) {
|
861
940
|
new_kb.namespace = project_id;
|
862
941
|
}
|
942
|
+
if (new_kb.type === 'txt') {
|
943
|
+
new_kb.scrape_type = 1;
|
944
|
+
}
|
945
|
+
if (new_kb.type === 'url') {
|
946
|
+
if (!body.scrape_type || body.scrape_type === 2) {
|
947
|
+
new_kb.scrape_type = 2;
|
948
|
+
new_kb.scrape_options = await setDefaultScrapeOptions();
|
949
|
+
} else {
|
950
|
+
new_kb.scrape_type = body.scrape_type;
|
951
|
+
new_kb.scrape_options = body.scrape_options;
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
863
955
|
winston.debug("adding kb: ", new_kb);
|
864
956
|
|
865
957
|
KB.findOneAndUpdate({ id_project: project_id, type: 'url', source: new_kb.source }, new_kb, { upsert: true, new: true, rawResult: true }, async (err, raw) => {
|
@@ -871,26 +963,37 @@ router.post('/', async (req, res) => {
|
|
871
963
|
|
872
964
|
res.status(200).send(raw);
|
873
965
|
|
966
|
+
let saved_kb = raw.value;
|
874
967
|
let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
|
875
968
|
|
876
969
|
let json = {
|
877
|
-
id:
|
878
|
-
type:
|
879
|
-
source:
|
970
|
+
id: saved_kb._id,
|
971
|
+
type: saved_kb.type,
|
972
|
+
source: saved_kb.source,
|
880
973
|
content: "",
|
881
|
-
namespace:
|
974
|
+
namespace: saved_kb.namespace,
|
882
975
|
webhook: webhook
|
883
976
|
}
|
884
977
|
winston.debug("json: ", json);
|
885
978
|
|
886
|
-
if (
|
887
|
-
json.content =
|
979
|
+
if (saved_kb.content) {
|
980
|
+
json.content = saved_kb.content;
|
981
|
+
}
|
982
|
+
if (saved_kb.scrape_type) {
|
983
|
+
json.scrape_type = saved_kb.scrape_type;
|
984
|
+
}
|
985
|
+
if (saved_kb.scrape_options) {
|
986
|
+
json.parameters_scrape_type_4 = saved_kb.scrape_options;
|
888
987
|
}
|
988
|
+
let ns = namespaces.find(n => n.id === body.namespace);
|
989
|
+
json.engine = ns.engine || default_engine;
|
889
990
|
|
890
991
|
let resources = [];
|
891
992
|
|
892
993
|
resources.push(json);
|
893
|
-
|
994
|
+
if (!process.env.NODE_ENV) {
|
995
|
+
scheduleScrape(resources);
|
996
|
+
}
|
894
997
|
|
895
998
|
}
|
896
999
|
})
|
@@ -908,6 +1011,8 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
908
1011
|
}
|
909
1012
|
|
910
1013
|
let project_id = req.projectid;
|
1014
|
+
let scrape_type = req.body.scrape_type;
|
1015
|
+
let scrape_options = req.body.scrape_options;
|
911
1016
|
|
912
1017
|
let namespace_id = req.query.namespace;
|
913
1018
|
if (!namespace_id) {
|
@@ -956,16 +1061,37 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
956
1061
|
let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
|
957
1062
|
|
958
1063
|
let kbs = [];
|
959
|
-
list.forEach(url => {
|
960
|
-
|
1064
|
+
list.forEach( async (url) => {
|
1065
|
+
let kb = {
|
961
1066
|
id_project: project_id,
|
962
1067
|
name: url,
|
963
1068
|
source: url,
|
964
1069
|
type: 'url',
|
965
1070
|
content: "",
|
966
1071
|
namespace: namespace_id,
|
967
|
-
status: -1
|
968
|
-
|
1072
|
+
status: -1,
|
1073
|
+
scrape_type: scrape_type
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
if (!kb.scrape_type) {
|
1077
|
+
scrape_type = 2;
|
1078
|
+
}
|
1079
|
+
|
1080
|
+
if (scrape_type == 2) {
|
1081
|
+
kb.scrape_options = {
|
1082
|
+
tags_to_extract: ["body"],
|
1083
|
+
unwanted_tags: [],
|
1084
|
+
unwanted_classnames: []
|
1085
|
+
}
|
1086
|
+
} else {
|
1087
|
+
kb.scrape_options = scrape_options;
|
1088
|
+
}
|
1089
|
+
// if (scrape_type === 2) {
|
1090
|
+
// kb.scrape_options = await setDefaultScrapeOptions();
|
1091
|
+
// } else {
|
1092
|
+
// kb.scrape_options = await setCustomScrapeOptions(scrape_options);
|
1093
|
+
// }
|
1094
|
+
kbs.push(kb)
|
969
1095
|
})
|
970
1096
|
|
971
1097
|
let operations = kbs.map(doc => {
|
@@ -979,13 +1105,20 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
979
1105
|
}
|
980
1106
|
})
|
981
1107
|
|
1108
|
+
console.log("kbs: ", kbs);
|
1109
|
+
|
982
1110
|
saveBulk(operations, kbs, project_id).then((result) => {
|
983
1111
|
|
1112
|
+
let ns = namespaces.find(n => n.id === namespace_id);
|
1113
|
+
let engine = ns.engine || default_engine;
|
1114
|
+
|
984
1115
|
let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
|
985
|
-
resources = resources.map(({ _id, ...rest }) => {
|
986
|
-
return { id: _id, webhook: webhook, ...rest
|
1116
|
+
resources = resources.map(({ _id, scrape_options, ...rest }) => {
|
1117
|
+
return { id: _id, webhook: webhook, parameters_scrape_type_4: scrape_options, engine: engine, ...rest}
|
987
1118
|
});
|
1119
|
+
console.log("resources to be sent to worker: ", resources);
|
988
1120
|
winston.verbose("resources to be sent to worker: ", resources);
|
1121
|
+
|
989
1122
|
scheduleScrape(resources);
|
990
1123
|
res.status(200).send(result);
|
991
1124
|
|
@@ -1085,9 +1218,13 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
|
|
1085
1218
|
})
|
1086
1219
|
|
1087
1220
|
saveBulk(operations, kbs, project_id).then((result) => {
|
1221
|
+
|
1222
|
+
let ns = namespaces.find(n => n.id === namespace_id);
|
1223
|
+
let engine = ns.engine || default_engine;
|
1224
|
+
|
1088
1225
|
let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
|
1089
1226
|
resources = resources.map(({ _id, ...rest}) => {
|
1090
|
-
return { id: _id, webhooh: webhook, ...rest };
|
1227
|
+
return { id: _id, webhooh: webhook, engine: engine, ...rest };
|
1091
1228
|
})
|
1092
1229
|
winston.verbose("resources to be sent to worker: ", resources);
|
1093
1230
|
if (!process.env.NODE_ENV) {
|
@@ -1166,7 +1303,6 @@ router.delete('/:kb_id', async (req, res) => {
|
|
1166
1303
|
let kb_id = req.params.kb_id;
|
1167
1304
|
winston.verbose("delete kb_id " + kb_id);
|
1168
1305
|
|
1169
|
-
|
1170
1306
|
let kb = await KB.findOne({ id_project: project_id, _id: kb_id}).catch((err) => {
|
1171
1307
|
winston.warn("Unable to find kb. Error: ", err);
|
1172
1308
|
return res.status(500).send({ success: false, error: err })
|
@@ -1186,6 +1322,16 @@ router.delete('/:kb_id', async (req, res) => {
|
|
1186
1322
|
data.namespace = project_id;
|
1187
1323
|
}
|
1188
1324
|
|
1325
|
+
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
1326
|
+
winston.error("find namespaces error: ", err)
|
1327
|
+
res.status(500).send({ success: false, error: err })
|
1328
|
+
})
|
1329
|
+
|
1330
|
+
let ns = namespaces.find(n => n.id === data.namespace);
|
1331
|
+
data.engine = ns.engine || default_engine;
|
1332
|
+
|
1333
|
+
winston.verbose("/:delete_id data: ", data);
|
1334
|
+
|
1189
1335
|
openaiService.deleteIndex(data).then((resp) => {
|
1190
1336
|
winston.debug("delete resp: ", resp.data);
|
1191
1337
|
if (resp.data.success === true) {
|
@@ -1369,6 +1515,30 @@ async function getKeyFromIntegrations(project_id) {
|
|
1369
1515
|
}
|
1370
1516
|
})
|
1371
1517
|
}
|
1518
|
+
|
1519
|
+
async function setDefaultScrapeOptions() {
|
1520
|
+
return {
|
1521
|
+
tags_to_extract: ["body"],
|
1522
|
+
unwanted_tags: [],
|
1523
|
+
unwanted_classnames: []
|
1524
|
+
}
|
1525
|
+
}
|
1526
|
+
|
1527
|
+
async function setCustomScrapeOptions(options) {
|
1528
|
+
if (!options) {
|
1529
|
+
options = await setDefaultScrapeOptions();
|
1530
|
+
} else {
|
1531
|
+
if (!options.tags_to_extract || options.tags_to_extract.length == 0) {
|
1532
|
+
options.tags_to_extract = ["body"];
|
1533
|
+
}
|
1534
|
+
if (!options.unwanted_tags) {
|
1535
|
+
options.unwanted_tags = [];
|
1536
|
+
}
|
1537
|
+
if (!options.unwanted_classnames) {
|
1538
|
+
options.unwanted_classnames = [];
|
1539
|
+
}
|
1540
|
+
}
|
1541
|
+
}
|
1372
1542
|
/**
|
1373
1543
|
* ****************************************
|
1374
1544
|
* Utils Methods Section - End
|
package/routes/project.js
CHANGED
@@ -13,7 +13,7 @@ var Group = require('../models/group');
|
|
13
13
|
|
14
14
|
var winston = require('../config/winston');
|
15
15
|
var roleChecker = require('../middleware/has-role');
|
16
|
-
|
16
|
+
var config = require('../config/database');
|
17
17
|
|
18
18
|
// THE THREE FOLLOWS IMPORTS ARE USED FOR AUTHENTICATION IN THE ROUTE
|
19
19
|
var passport = require('passport');
|
@@ -25,6 +25,24 @@ var orgUtil = require("../utils/orgUtil");
|
|
25
25
|
var cacheEnabler = require("../services/cacheEnabler");
|
26
26
|
var mongoose = require('mongoose');
|
27
27
|
|
28
|
+
var jwt = require('jsonwebtoken');
|
29
|
+
// CHECK IT ASAP!!!!
|
30
|
+
let configSecret = process.env.GLOBAL_SECRET || config.secret;
|
31
|
+
var pKey = process.env.GLOBAL_SECRET_OR_PRIVATE_KEY;
|
32
|
+
// console.log("pKey",pKey);
|
33
|
+
|
34
|
+
if (pKey) {
|
35
|
+
configSecret = pKey.replace(/\\n/g, '\n');
|
36
|
+
}
|
37
|
+
|
38
|
+
let pubConfigSecret = process.env.GLOBAL_SECRET || config.secret;
|
39
|
+
var pubKey = process.env.GLOBAL_SECRET_OR_PUB_KEY;
|
40
|
+
if (pubKey) {
|
41
|
+
pubConfigSecret = pubKey.replace(/\\n/g, '\n');
|
42
|
+
}
|
43
|
+
// CHECK IT ASAP!!!!
|
44
|
+
|
45
|
+
|
28
46
|
router.post('/', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken], async (req, res) => {
|
29
47
|
|
30
48
|
// create(name, createdBy, settings)
|
@@ -735,6 +753,95 @@ Project.findByIdAndUpdate(req.params.projectid, { $pull: { bannedUsers: { "_id":
|
|
735
753
|
|
736
754
|
});
|
737
755
|
|
756
|
+
router.get('/all', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken], function (req, res) {
|
757
|
+
|
758
|
+
if (req.headers.authorization) {
|
759
|
+
|
760
|
+
let token = req.headers.authorization.split(" ")[1];
|
761
|
+
let decode = jwt.verify(token, pubConfigSecret)
|
762
|
+
if (decode && (decode.email === process.env.ADMIN_EMAIL)) {
|
763
|
+
|
764
|
+
Project.aggregate([
|
765
|
+
// {
|
766
|
+
// $match: {
|
767
|
+
// status: 100,
|
768
|
+
// //createdAt: { $gte: startDate}
|
769
|
+
// },
|
770
|
+
// },
|
771
|
+
{
|
772
|
+
$sort: {
|
773
|
+
createdAt: -1
|
774
|
+
},
|
775
|
+
},
|
776
|
+
{
|
777
|
+
$lookup: {
|
778
|
+
from: 'project_users',
|
779
|
+
localField: '_id',
|
780
|
+
foreignField: 'id_project',
|
781
|
+
as: 'project_user',
|
782
|
+
pipeline: [
|
783
|
+
{ $match: { role: 'owner' } }
|
784
|
+
]
|
785
|
+
}
|
786
|
+
},
|
787
|
+
{
|
788
|
+
$addFields: {
|
789
|
+
project_user: { $arrayElemAt: ['$project_user', 0] }
|
790
|
+
}
|
791
|
+
},
|
792
|
+
{
|
793
|
+
$lookup: {
|
794
|
+
from: 'users',
|
795
|
+
localField: 'project_user.id_user',
|
796
|
+
foreignField: '_id',
|
797
|
+
as: 'user'
|
798
|
+
},
|
799
|
+
},
|
800
|
+
{
|
801
|
+
$addFields: {
|
802
|
+
user: { $arrayElemAt: ['$user', 0] }
|
803
|
+
}
|
804
|
+
}
|
805
|
+
])
|
806
|
+
.then((projects) => {
|
807
|
+
winston.verbose("Projects found " + projects.length)
|
808
|
+
// const fieldsToKeep = ['_id', 'name', 'createdBy', 'createdAt', 'user.email' ];
|
809
|
+
|
810
|
+
const filteredProjects = projects.map(project => {
|
811
|
+
const filteredProject = {};
|
812
|
+
filteredProject._id = project._id;
|
813
|
+
filteredProject.name = project.name;
|
814
|
+
filteredProject.owner = project.user?.email;
|
815
|
+
filteredProject.createdAt = project.createdAt;
|
816
|
+
filteredProject.profile_name = project.profile?.name;
|
817
|
+
// ... add other fields here
|
818
|
+
|
819
|
+
// fieldsToKeep.forEach(field => {
|
820
|
+
// if (project[field] !== undefined) {
|
821
|
+
// filteredProject[field] = project[field];
|
822
|
+
// }
|
823
|
+
// });
|
824
|
+
return filteredProject;
|
825
|
+
});
|
826
|
+
|
827
|
+
return res.status(200).send(filteredProjects);
|
828
|
+
})
|
829
|
+
.catch((err) => {
|
830
|
+
console.error(err);
|
831
|
+
return res.status(500).send({ success: false, error: err});
|
832
|
+
});
|
833
|
+
|
834
|
+
// let updatedUser = await User.findByIdAndUpdate(savedUser._id, { emailverified: true }, { new: true }).exec();
|
835
|
+
// winston.debug("updatedUser: ", updatedUser);
|
836
|
+
// skipVerificationEmail = true;
|
837
|
+
// winston.verbose("skip sending verification email")
|
838
|
+
} else {
|
839
|
+
return res.status(403).send({ success: false, error: "You don't have the permission required to perform the operation"});
|
840
|
+
}
|
841
|
+
|
842
|
+
}
|
843
|
+
|
844
|
+
});
|
738
845
|
|
739
846
|
|
740
847
|
//roleChecker.hasRole('agent') works because req.params.projectid is valid using :projectid of this method
|