@tiledesk/tiledesk-server 2.4.7 → 2.4.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/app.js +11 -0
  3. package/config/email.js +1 -1
  4. package/event/botEvent.js +12 -2
  5. package/middleware/has-role.js +6 -0
  6. package/middleware/passport.js +1 -0
  7. package/models/auth.js +9 -1
  8. package/models/faq_kb.js +4 -0
  9. package/models/lead.js +5 -0
  10. package/models/user.js +3 -0
  11. package/package.json +3 -3
  12. package/public/wstest/index.html +5 -41
  13. package/pubmodules/apps/listener.js +3 -3
  14. package/pubmodules/queue/reconnect.js +24 -0
  15. package/pubmodules/queue/reconnectFanout.js +17 -0
  16. package/routes/auth.js +44 -3
  17. package/routes/faq_kb.js +42 -0
  18. package/routes/images.js +3 -1
  19. package/routes/lead.js +51 -0
  20. package/routes/project.js +12 -0
  21. package/routes/users.js +2 -0
  22. package/services/emailService.js +2 -2
  23. package/services/trainingService.js +7 -2
  24. package/template/email/assignedEmailMessage.html +253 -149
  25. package/template/email/assignedRequest.html +273 -173
  26. package/template/email/beenInvitedExistingUser.html +213 -130
  27. package/template/email/beenInvitedNewUser.html +200 -119
  28. package/template/email/emailDirect.html +207 -114
  29. package/template/email/newMessage.html +250 -157
  30. package/template/email/newMessageFollower.html +351 -225
  31. package/template/email/passwordChanged.html +178 -96
  32. package/template/email/pooledEmailMessage.html +250 -151
  33. package/template/email/pooledRequest.html +270 -164
  34. package/template/email/resetPassword.html +201 -115
  35. package/template/email/sendTranscript.html +299 -197
  36. package/template/email/ticket.html +263 -160
  37. package/template/email/verify.html +208 -126
  38. package/websocket/webSocketServer.js +70 -3
@@ -16,7 +16,7 @@ jobs:
16
16
  # You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
17
17
  # A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/node
18
18
  docker:
19
- - image: cimg/node:15.1
19
+ - image: cimg/node:16.17.1
20
20
  # Then run your tests!
21
21
  # CircleCI will report the results back to your VCS provider.
22
22
  steps:
package/app.js CHANGED
@@ -132,6 +132,7 @@ var settingDataLoader = require('./services/settingDataLoader');
132
132
  var schemaMigrationService = require('./services/schemaMigrationService');
133
133
  var RouterLogger = require('./models/routerLogger');
134
134
  var cacheEnabler = require("./services/cacheEnabler");
135
+ const session = require('express-session');
135
136
 
136
137
  require('./services/mongoose-cache-fn')(mongoose);
137
138
 
@@ -270,6 +271,16 @@ if (process.env.ENABLE_ACCESSLOG) {
270
271
 
271
272
  app.use(passport.initialize());
272
273
 
274
+ // After you declare "app"
275
+ if (process.env.DISABLE_SESSION_STRATEGY==true || process.env.DISABLE_SESSION_STRATEGY=="true" ) {
276
+ winston.info("Express Session disabled");
277
+ } else {
278
+ // https://www.npmjs.com/package/express-session
279
+ let sessionSecret = process.env.SESSION_SECRET || "tiledesk-session-secret";
280
+ winston.info("Express Session Secret: " + sessionSecret);
281
+ app.use(session({ secret: sessionSecret}));
282
+ app.use(passport.session());
283
+ }
273
284
 
274
285
  //ATTENTION. If you use AWS Api Gateway you need also to configure the cors policy https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html
275
286
  app.use(cors());
package/config/email.js CHANGED
@@ -3,7 +3,7 @@ module.exports = {
3
3
  'username': 'postmaster@mg.tiledesk.com',
4
4
  'from': 'Tiledesk Notification <postmaster@mg.tiledesk.com>',
5
5
  'bcc': '',
6
- 'baseUrl':'https://console.tiledesk.com/v2/dashboard',
6
+ 'baseUrl':'http://localhost:8081/dashboard',
7
7
  'replyEnabled' : false,
8
8
  'inboundDomain': 'tickets.tiledesk.com'
9
9
  };
package/event/botEvent.js CHANGED
@@ -3,12 +3,20 @@ const messageEvent = require('../event/messageEvent');
3
3
  const Faq_kb = require('../models/faq_kb');
4
4
  var winston = require('../config/winston');
5
5
 
6
- class BotEvent extends EventEmitter {}
6
+
7
7
  const cacheUtil = require("../utils/cacheUtil");
8
8
  const cacheEnabler = require("../services/cacheEnabler");
9
9
 
10
- const botEvent = new BotEvent();
10
+ // class BotEvent extends EventEmitter {}
11
+ class BotEvent extends EventEmitter {
12
+ constructor() {
13
+ super();
14
+ this.queueEnabled = false;
15
+ this.setMaxListeners(11);
16
+ }
17
+ }
11
18
 
19
+ const botEvent = new BotEvent();
12
20
 
13
21
  //TODO use request. getBotId
14
22
  function getBotFromParticipants(participants) {
@@ -111,8 +119,10 @@ messageEvent.on('message.create', function(message) {
111
119
 
112
120
 
113
121
  let qbot = Faq_kb.findById(botId); //TODO add cache_bot_here
122
+ //TODO unselect secret. secret is unselectable by default in the model
114
123
 
115
124
  if (cacheEnabler.faq_kb) {
125
+ winston.debug('message.id_project+":faq_kbs:id:"+botId: '+ message.id_project+":faq_kbs:id:"+botId);
116
126
  qbot.cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+botId)
117
127
  winston.debug('faq_kb cache enabled');
118
128
  }
@@ -50,6 +50,12 @@ class RoleChecker {
50
50
  return true
51
51
  } else {
52
52
  winston.debug("isTypeAsFunction is false");
53
+
54
+ var adminEmail = process.env.ADMIN_EMAIL || "admin@tiledesk.com";
55
+
56
+ if (user && user.email && user.email === adminEmail) { //skip has role check
57
+ return true;
58
+ }
53
59
  return false;
54
60
  }
55
61
  }
@@ -511,6 +511,7 @@ if (enableGoogleSignin==true) {
511
511
 
512
512
  var auth = new Auth({
513
513
  providerId: issuer,
514
+ email: email,
514
515
  subject: profile.id,
515
516
  });
516
517
  auth.save(function (err, authSaved) {
package/models/auth.js CHANGED
@@ -12,9 +12,17 @@ var AuthSchema = new Schema({
12
12
  default: 'password',
13
13
  required: true
14
14
  },
15
+ subject: {
16
+ type: String,
17
+ required: true
18
+ },
19
+ email: {
20
+ type: String,
21
+ },
15
22
  password: {
16
23
  type: String,
17
- required: true,
24
+ required: false,
25
+ // required: true,
18
26
  // https://stackoverflow.com/questions/12096262/how-to-protect-the-password-field-in-mongoose-mongodb-so-it-wont-return-in-a-qu
19
27
  // select: false
20
28
  },
package/models/faq_kb.js CHANGED
@@ -105,6 +105,10 @@ var Faq_kbSchema = new Schema({
105
105
  publishedAt: {
106
106
  type: Date
107
107
  },
108
+ trained: {
109
+ type: Boolean,
110
+ default: true
111
+ },
108
112
  },{
109
113
  timestamps: true
110
114
  }
package/models/lead.js CHANGED
@@ -88,6 +88,9 @@ var LeadSchema = new Schema({
88
88
  default: LeadConstants.NORMAL,
89
89
  index: true
90
90
  },
91
+ properties: {
92
+ type: Object,
93
+ },
91
94
  },{
92
95
  timestamps: true
93
96
  }
@@ -102,6 +105,8 @@ LeadSchema.index({fullname: 'text', email: 'text'},
102
105
  // suggested by atlas
103
106
  LeadSchema.index({status: 1, id_project: 1, createdAt: -1});
104
107
 
108
+
109
+
105
110
  var lead = mongoose.model('lead', LeadSchema);
106
111
 
107
112
  if (process.env.MONGOOSE_SYNCINDEX) {
package/models/user.js CHANGED
@@ -55,6 +55,9 @@ var UserSchema = new Schema({
55
55
  index: true,
56
56
  // select: false
57
57
  },
58
+ description: {
59
+ type: String,
60
+ },
58
61
  // authType: { // update db old data
59
62
  // type: String,
60
63
  // index:true,
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.4.7",
4
+ "version": "2.4.9",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -44,8 +44,8 @@
44
44
  "@tiledesk/tiledesk-kaleyra-proxy": "^0.1.7",
45
45
  "@tiledesk/tiledesk-messenger-connector": "0.1.9",
46
46
  "@tiledesk/tiledesk-rasa-connector": "^1.0.10",
47
- "@tiledesk/tiledesk-tybot-connector": "^0.1.77",
48
- "@tiledesk/tiledesk-whatsapp-connector": "^0.1.45",
47
+ "@tiledesk/tiledesk-tybot-connector": "^0.1.78",
48
+ "@tiledesk/tiledesk-whatsapp-connector": "^0.1.46",
49
49
  "amqplib": "^0.5.5",
50
50
  "app-root-path": "^3.0.0",
51
51
  "bcrypt-nodejs": "0.0.3",
@@ -5,55 +5,19 @@
5
5
 
6
6
  <!-- <script type="text/javascript" src="./main.js"></script> -->
7
7
 
8
- // var ws = new WebSocket('wss://rtm.tiledesk.com/?token=JWT%20eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWI0NWZiMjFmOWUxZjAwMTJkNjIyMDEiLCJlbWFpbCI6ImExQGExLml0IiwiZmlyc3RuYW1lIjoiYTEiLCJsYXN0bmFtZSI6ImExIiwiZW1haWx2ZXJpZmllZCI6ZmFsc2UsImlhdCI6MTU4ODg3OTI4NCwiYXVkIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJpc3MiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsInN1YiI6InVzZXIiLCJqdGkiOiI5MGIzNTY1NS1jNzY4LTQwMjEtODIyNy1hYWQ1MGU5NWFmYTEifQ.v4RjqtpM-kqa_PGVXmn9eJOeb3IWrcXH0U6V5iJrj7U');
9
-
10
8
  <script>
11
- var ws = new WebSocket('wss://rtm.tiledesk.com/?token=JWT%20eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWI1NmUxYTFmOWUxZjAwMTJkNjIyNzUiLCJlbWFpbCI6ImxvYWRAbG9hZC5pdCIsImZpcnN0bmFtZSI6ImxvYWQiLCJsYXN0bmFtZSI6ImxvYWQiLCJlbWFpbHZlcmlmaWVkIjpmYWxzZSwiaWF0IjoxNTg4OTQ4NTA3LCJhdWQiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsImlzcyI6Imh0dHBzOi8vdGlsZWRlc2suY29tIiwic3ViIjoidXNlciIsImp0aSI6IjU0OWQ3ODI4LWI5ZDAtNDAxNS1iMDQ4LTA0M2IyYzYyZjAxOSJ9.gnGJRtUoRpUA90QWNSp1wmWmlJcu1YwYf_kJ8yUi1_I');
9
+ var ws = new WebSocket('ws://localhost:3000/?token=JWT%20eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWU4OTE5ZDg3MjJiMzAwMzQ3ZWM1NmYiLCJlbWFpbCI6ImFkbWluQHRpbGVkZXNrLmNvbSIsImZpcnN0bmFtZSI6IkFkbWluaXN0cmF0b3IiLCJsYXN0bmFtZSI6IiAiLCJlbWFpbHZlcmlmaWVkIjp0cnVlLCJpYXQiOjE2ODM2NTEyMDYsImF1ZCI6Imh0dHBzOi8vdGlsZWRlc2suY29tIiwiaXNzIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJzdWIiOiJ1c2VyIiwianRpIjoiZDVlY2U3YjctN2U0Zi00NThmLTkxYWMtNGJiMzY3NDdmNmUxIn0.KiPGusVCPR0-IROsoPiH93V_vCKJS3rK_ikjqmngQT7J_s3VHalRvGfuvds-sRg4V8rfZyhlfaR6uWR71TYPhyT7REPYORp-T-6ddb8g7nL4lraHVhzqYYpVPIhXUM81rkyHm1FP2LuIsEe93Ir62AyK0xajoS1wPdjYNBxari0');
10
+ // var ws = new WebSocket('ws://eu.rtmv3.tiledesk.com/mqws/ws/?token=JWT%20eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWI1NmUxYTFmOWUxZjAwMTJkNjIyNzUiLCJlbWFpbCI6ImxvYWRAbG9hZC5pdCIsImZpcnN0bmFtZSI6ImxvYWQiLCJsYXN0bmFtZSI6ImxvYWQiLCJlbWFpbHZlcmlmaWVkIjpmYWxzZSwiaWF0IjoxNTg4OTQ4NTA3LCJhdWQiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsImlzcyI6Imh0dHBzOi8vdGlsZWRlc2suY29tIiwic3ViIjoidXNlciIsImp0aSI6IjU0OWQ3ODI4LWI5ZDAtNDAxNS1iMDQ4LTA0M2IyYzYyZjAxOSJ9.gnGJRtUoRpUA90QWNSp1wmWmlJcu1YwYf_kJ8yUi1_I');
12
11
  ws.onopen = function () {
13
- console.log('websocket is connected2 ...');
14
- ws.send('{ "action": "subscribe", "payload": { "topic": "/5eb56e211f9e1f0012d6227b/requests"}}');
12
+ console.log('websocket is connected ...');
13
+ ws.send('{ "action": "subscribe", "payload": { "topic": "/6453d246f1e784003a97537b/bots/645903253e16b1002cfe4439"}}');
14
+ // ws.send('{ "action": "subscribe", "payload": { "topic": "/5eb56e211f9e1f0012d6227b/requests"}}');
15
15
  }
16
16
  </script>
17
17
 
18
18
 
19
19
 
20
20
 
21
-
22
- <script>
23
- var ws = new WebSocket('wss://tiledesk-server-pre.herokuapp.com/?token=JWT%20eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YWFhOTkwMjRjM2IxMTAwMTRiNDc4ZjAiLCJlbWFpbCI6ImFuZHJlYS5sZW9AZnJvbnRpZXJlMjEuaXQiLCJmaXJzdG5hbWUiOiJBbmRyZWEiLCJsYXN0bmFtZSI6IkxlbyIsImVtYWlsdmVyaWZpZWQiOnRydWUsImlhdCI6MTU4NzU0NjIyNiwiYXVkIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJpc3MiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsInN1YiI6InVzZXIiLCJqdGkiOiJkNDNhMmIwNi1jZGRkLTRkZDYtYjhiNC02NzdiOGI4MTQyYjIifQ.KZGvjr8oQc2sYeV1bOMvCd0_9XxaLlfIszjT_4-PlQ4');
24
-
25
- ws.onopen = function () {
26
- console.log('websocket is connected2 ...');
27
- ws.send('{ "action": "subscribe", "payload": { "topic": "/5ebae6f21aee9b0034511f65/requests"}}');
28
- }
29
- </script>
30
-
31
-
32
-
33
-
34
-
35
- <script>
36
-
37
-
38
- //var url = 'ws://'+window.location.host+'/?token=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyIkX18iOnsic3RyaWN0TW9kZSI6dHJ1ZSwic2VsZWN0ZWQiOnsiZW1haWwiOjEsImZpcnN0bmFtZSI6MSwibGFzdG5hbWUiOjEsInBhc3N3b3JkIjoxLCJlbWFpbHZlcmlmaWVkIjoxLCJpZCI6MX0sImdldHRlcnMiOnt9LCJfaWQiOiI1ZGM5Mzg2MmFkZDRmNjljM2Q0NThkOGYiLCJ3YXNQb3B1bGF0ZWQiOmZhbHNlLCJhY3RpdmVQYXRocyI6eyJwYXRocyI6eyJwYXNzd29yZCI6ImluaXQiLCJlbWFpbCI6ImluaXQiLCJlbWFpbHZlcmlmaWVkIjoiaW5pdCIsIl9pZCI6ImluaXQifSwic3RhdGVzIjp7Imlnbm9yZSI6e30sImRlZmF1bHQiOnt9LCJpbml0Ijp7ImVtYWlsdmVyaWZpZWQiOnRydWUsInBhc3N3b3JkIjp0cnVlLCJlbWFpbCI6dHJ1ZSwiX2lkIjp0cnVlfSwibW9kaWZ5Ijp7fSwicmVxdWlyZSI6e319LCJzdGF0ZU5hbWVzIjpbInJlcXVpcmUiLCJtb2RpZnkiLCJpbml0IiwiZGVmYXVsdCIsImlnbm9yZSJdfSwicGF0aHNUb1Njb3BlcyI6e30sImVtaXR0ZXIiOnsiX2V2ZW50cyI6e30sIl9ldmVudHNDb3VudCI6MCwiX21heExpc3RlbmVycyI6MH0sIiRvcHRpb25zIjp0cnVlfSwiaXNOZXciOmZhbHNlLCJfZG9jIjp7ImVtYWlsdmVyaWZpZWQiOmZhbHNlLCJwYXNzd29yZCI6IiQyYSQxMCRJc0hJRm9HTmRvRnVrODVRaDZlbXN1RjFzbkphNC5ELmgud2tuS092RUdlcVJsSlpZOHdjUyIsImVtYWlsIjoiYW5kcmVhLmxlb0BmMjEuaXQiLCJfaWQiOiI1ZGM5Mzg2MmFkZDRmNjljM2Q0NThkOGYifSwiJGluaXQiOnRydWUsImlhdCI6MTU3NDYxNTY2MSwiYXVkIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJpc3MiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsInN1YiI6InVzZXIifQ.6DjvyVO-4zuHH2kdfItWx9eVGZ-HcRcs1jehVRrDWpE';
39
- //var url = 'ws://'+window.location.host+'/?token=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyIkX18iOnsic3RyaWN0TW9kZSI6dHJ1ZSwic2VsZWN0ZWQiOnsiZW1haWwiOjEsImZpcnN0bmFtZSI6MSwibGFzdG5hbWUiOjEsInBhc3N3b3JkIjoxLCJlbWFpbHZlcmlmaWVkIjoxLCJpZCI6MX0sImdldHRlcnMiOnt9LCJfaWQiOiI1ZGM5Mzg2MmFkZDRmNjljM2Q0NThkOGYiLCJ3YXNQb3B1bGF0ZWQiOmZhbHNlLCJhY3RpdmVQYXRocyI6eyJwYXRocyI6eyJwYXNzd29yZCI6ImluaXQiLCJlbWFpbCI6ImluaXQiLCJlbWFpbHZlcmlmaWVkIjoiaW5pdCIsIl9pZCI6ImluaXQifSwic3RhdGVzIjp7Imlnbm9yZSI6e30sImRlZmF1bHQiOnt9LCJpbml0Ijp7ImVtYWlsdmVyaWZpZWQiOnRydWUsInBhc3N3b3JkIjp0cnVlLCJlbWFpbCI6dHJ1ZSwiX2lkIjp0cnVlfSwibW9kaWZ5Ijp7fSwicmVxdWlyZSI6e319LCJzdGF0ZU5hbWVzIjpbInJlcXVpcmUiLCJtb2RpZnkiLCJpbml0IiwiZGVmYXVsdCIsImlnbm9yZSJdfSwicGF0aHNUb1Njb3BlcyI6e30sImVtaXR0ZXIiOnsiX2V2ZW50cyI6e30sIl9ldmVudHNDb3VudCI6MCwiX21heExpc3RlbmVycyI6MH0sIiRvcHRpb25zIjp0cnVlfSwiaXNOZXciOmZhbHNlLCJfZG9jIjp7ImVtYWlsdmVyaWZpZWQiOmZhbHNlLCJwYXNzd29yZCI6IiQyYSQxMCRJc0hJRm9HTmRvRnVrODVRaDZlbXN1RjFzbkphNC5ELmgud2tuS092RUdlcVJsSlpZOHdjUyIsImVtYWlsIjoiYW5kcmVhLmxlb0BmMjEuaXQiLCJfaWQiOiI1ZGM5Mzg2MmFkZDRmNjljM2Q0NThkOGYifSwiJGluaXQiOnRydWUsImlhdCI6MTU3NDkzNTUxOCwiYXVkIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJpc3MiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsInN1YiI6InVzZXIifQ._fZWRXAG1lBwmEbrqmvQr1ghhbcKAHgs74ki8UtDBZU';
40
- //var url = 'ws://'+window.location.host+'/?token=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyIkX18iOnsic3RyaWN0TW9kZSI6dHJ1ZSwic2VsZWN0ZWQiOnsiZW1haWwiOjEsImZpcnN0bmFtZSI6MSwibGFzdG5hbWUiOjEsInBhc3N3b3JkIjoxLCJlbWFpbHZlcmlmaWVkIjoxLCJpZCI6MX0sImdldHRlcnMiOnt9LCJfaWQiOiI1YWIxMWM2YjgzZGMyNDAwMTRkNDYwOTUiLCJ3YXNQb3B1bGF0ZWQiOmZhbHNlLCJhY3RpdmVQYXRocyI6eyJwYXRocyI6eyJwYXNzd29yZCI6ImluaXQiLCJlbWFpbCI6ImluaXQiLCJfaWQiOiJpbml0In0sInN0YXRlcyI6eyJpZ25vcmUiOnt9LCJkZWZhdWx0Ijp7fSwiaW5pdCI6eyJwYXNzd29yZCI6dHJ1ZSwiZW1haWwiOnRydWUsIl9pZCI6dHJ1ZX0sIm1vZGlmeSI6e30sInJlcXVpcmUiOnt9fSwic3RhdGVOYW1lcyI6WyJyZXF1aXJlIiwibW9kaWZ5IiwiaW5pdCIsImRlZmF1bHQiLCJpZ25vcmUiXX0sInBhdGhzVG9TY29wZXMiOnt9LCJlbWl0dGVyIjp7Il9ldmVudHMiOnt9LCJfZXZlbnRzQ291bnQiOjAsIl9tYXhMaXN0ZW5lcnMiOjB9LCIkb3B0aW9ucyI6dHJ1ZX0sImlzTmV3IjpmYWxzZSwiX2RvYyI6eyJwYXNzd29yZCI6IiQyYSQxMCQ1eDUvUHJYWTJycVZTdVRQLjV2WlEuQ3JScy5sLjVWS2svNzRIb2haTXFwaEJwWHpNRUZKMiIsImVtYWlsIjoiYW5kcmVhLmxlb0BmMjEuaXQiLCJfaWQiOiI1YWIxMWM2YjgzZGMyNDAwMTRkNDYwOTUifSwiJGluaXQiOnRydWUsImlhdCI6MTU3NTAxODYzNiwiYXVkIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJpc3MiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsInN1YiI6InVzZXIifQ.ZNU49DGQNdWfPMui_J1D9QyMnBgNIiS6q92TVGVW5m4';
41
- var url = 'ws://104.198.139.15'+'/?token=JWT%20eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZThkYTJiZTljMWY1MjAwMTdlZGJkZWYiLCJlbWFpbCI6ImFuZHJlYS5sZW9AZnJvbnRpZXJlMjEuaXQiLCJmaXJzdG5hbWUiOiJhbmRyZWEiLCJsYXN0bmFtZSI6ImxlbyIsImVtYWlsdmVyaWZpZWQiOnRydWUsImlhdCI6MTU4NjQxNjM0NSwiYXVkIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJpc3MiOiJodHRwczovL3RpbGVkZXNrLmNvbSIsInN1YiI6InVzZXIiLCJqdGkiOiI1ZDg1M2Q3Ny01YzJjLTQ3ZmQtOWFiMy1lZjJlZDg2ZDQyN2EifQ.s7zqrF7CrfEwlbbkb-cg8lc7VrzXRQsPRv1PVtTVqSM';
42
-
43
-
44
- tilebase = new Tilebase(url
45
-
46
- , function(data, notification) {
47
- $('#messages').append(`<div id="${data._id}">${data.first_text} ${notification.event.method}</div>`);
48
- }
49
- , function(object, notification) {
50
- $('#'+data._id).html(`<div id="${data._id}">${data.first_text} ${notification.event.method}</div>`);
51
- }
52
- );
53
- //tilebase.start('{ "action": "subscribe", "payload": { "topic": "topic1"}}');
54
- tilebase.start();
55
-
56
- </script>
57
21
  </head>
58
22
  <bdoy>
59
23
  <h1>
@@ -6,13 +6,13 @@ var config = require('../../config/database'); // get db config file
6
6
  let configSecretOrPubicKay = process.env.GLOBAL_SECRET || config.secret;
7
7
 
8
8
  var pKey = process.env.GLOBAL_SECRET_OR_PUB_KEY;
9
- console.log("pKey",pKey);
9
+ // console.log("pKey",pKey);
10
10
 
11
11
  if (pKey) {
12
12
  configSecretOrPubicKay = pKey.replace(/\\n/g, '\n');
13
13
  }
14
14
 
15
- console.log("configSecretOrPubicKay",configSecretOrPubicKay);
15
+ // console.log("configSecretOrPubicKay",configSecretOrPubicKay);
16
16
 
17
17
  class Listener {
18
18
 
@@ -23,7 +23,7 @@ class Listener {
23
23
  if (config.databaseUri) {
24
24
  winston.debug("apps config databaseUri: " + config.databaseUri);
25
25
  }
26
- console.log("ACCESS_TOKEN_SECRET",process.env.APPS_ACCESS_TOKEN_SECRET || configSecretOrPubicKay);
26
+ // console.log("ACCESS_TOKEN_SECRET",process.env.APPS_ACCESS_TOKEN_SECRET || configSecretOrPubicKay);
27
27
 
28
28
  apps.startApp({
29
29
  ACCESS_TOKEN_SECRET: process.env.APPS_ACCESS_TOKEN_SECRET || configSecretOrPubicKay,
@@ -2,6 +2,7 @@ var amqp = require('amqplib/callback_api');
2
2
  var winston = require('../../config/winston');
3
3
  const requestEvent = require('../../event/requestEvent');
4
4
  const messageEvent = require('../../event/messageEvent');
5
+ const botEvent = require('../../event/botEvent');
5
6
  const authEvent = require('../../event/authEvent');
6
7
  // https://elements.heroku.com/addons/cloudamqp
7
8
  // https://gist.github.com/carlhoerberg/006b01ac17a0a94859ba#file-reconnect-js
@@ -149,6 +150,13 @@ function startWorker() {
149
150
  winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: project_user_update");
150
151
  winston.info("Data queue", oka)
151
152
  });
153
+
154
+ ch.bindQueue(_ok.queue, exchange, "faqbot_update", {}, function(err3, oka) {
155
+ winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: faqbot_update");
156
+ winston.info("Data queue", oka)
157
+ });
158
+
159
+
152
160
  ch.consume("jobs", processMsg, { noAck: false });
153
161
  winston.info("Worker is started");
154
162
  });
@@ -222,6 +230,12 @@ function work(msg, cb) {
222
230
  // requestEvent.emit('request.create.queue', msg.content);
223
231
  authEvent.emit('project_user.update.queue', JSON.parse(message_string));
224
232
  }
233
+
234
+ if (topic === 'faqbot_update') {
235
+ winston.info("reconnect here topic faqbot_update:" + topic);
236
+ // requestEvent.emit('request.update.queue', msg.content);
237
+ botEvent.emit('faqbot.update.queue', JSON.parse(message_string));
238
+ }
225
239
  cb(true);
226
240
  // WebSocket.cb(true);
227
241
  // requestEvent.on(msg.KEYYYYYYY+'.ws', msg.content);
@@ -318,12 +332,22 @@ function listen() {
318
332
  });
319
333
  });
320
334
 
335
+
336
+ botEvent.on('faqbot.update', function(bot) {
337
+ setImmediate(() => {
338
+ winston.debug("reconnect faqbot.update")
339
+ publish(exchange, "faqbot_update", Buffer.from(JSON.stringify(bot)));
340
+ winston.info("reconnect: "+ Buffer.from(JSON.stringify(bot)))
341
+ });
342
+ });
343
+
321
344
  }
322
345
 
323
346
  if (process.env.QUEUE_ENABLED === "true") {
324
347
  requestEvent.queueEnabled = true;
325
348
  messageEvent.queueEnabled = true;
326
349
  authEvent.queueEnabled = true;
350
+ botEvent.queueEnabled = true;
327
351
  listen();
328
352
  start();
329
353
  winston.info("Queue enabled. endpint: " + url );
@@ -2,6 +2,7 @@ var amqp = require('amqplib/callback_api');
2
2
  var winston = require('../../config/winston');
3
3
  const requestEvent = require('../../event/requestEvent');
4
4
  const messageEvent = require('../../event/messageEvent');
5
+ const botEvent = require('../../event/botEvent');
5
6
  const authEvent = require('../../event/authEvent');
6
7
  // https://elements.heroku.com/addons/cloudamqp
7
8
  // https://gist.github.com/carlhoerberg/006b01ac17a0a94859ba#file-reconnect-js
@@ -179,6 +180,10 @@ function work(msg, cb) {
179
180
  winston.debug("reconnectfanout here topic:" + topic);
180
181
  authEvent.emit('project_user.update.queue.pubsub', JSON.parse(message_string));
181
182
  }
183
+ if (topic === 'faqbot_update') {
184
+ winston.info("reconnectfanout here topic faqbot_update:" + topic);
185
+ botEvent.emit('faqbot.update.queue.pubsub', JSON.parse(message_string));
186
+ }
182
187
  cb(true);
183
188
  // WebSocket.cb(true);
184
189
  // requestEvent.on(msg.KEYYYYYYY+'.ws', msg.content);
@@ -243,12 +248,24 @@ function listen() {
243
248
  publish(exchange, "project_user_update", Buffer.from(JSON.stringify(dat)));
244
249
  });
245
250
  });
251
+
252
+
253
+ botEvent.on('faqbot.update', function(bot) {
254
+ setImmediate(() => {
255
+ winston.debug("reconnect faqbot.update")
256
+ publish(exchange, "faqbot_update", Buffer.from(JSON.stringify(bot)));
257
+ winston.info("reconnect fan: "+ Buffer.from(JSON.stringify(bot)))
258
+ });
259
+ });
260
+
261
+
246
262
  }
247
263
 
248
264
  if (process.env.QUEUE_ENABLED === "true") {
249
265
  requestEvent.queueEnabled = true;
250
266
  messageEvent.queueEnabled = true;
251
267
  authEvent.queueEnabled = true;
268
+ botEvent.queueEnabled = true;
252
269
  listen();
253
270
  start();
254
271
  winston.info("Queue Fanout enabled. endpint: " + url );
package/routes/auth.js CHANGED
@@ -452,9 +452,31 @@ function (req, res) {
452
452
  });
453
453
 
454
454
 
455
+ // http://localhost:3000/auth/google?redirect_url=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fgoogle%2Fcallback%3Ffrom%3Dsignup
456
+
457
+ // http://localhost:3000/auth/google?redirect_url=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fgoogle%2Fcallbacks
458
+
459
+ // http://localhost:3000/auth/google?redirect_url=%2F%23%2Fproject%2F6452281f6d68c5f419c1c577%2Fhome
460
+
461
+
455
462
 
456
463
  // Redirect the user to the Google signin page</em>
457
- router.get("/google", passport.authenticate("google", { scope: ["email", "profile"] }));
464
+ // router.get("/google", passport.authenticate("google", { scope: ["email", "profile"] }));
465
+ router.get("/google", function(req,res,next){
466
+ winston.info("redirect_url: "+ req.query.redirect_url );
467
+ req.session.redirect_url = req.query.redirect_url;
468
+ // req._toParam = 'Hello';
469
+ passport.authenticate(
470
+ // 'google', { scope : ["email", "profile"], state: base64url(JSON.stringify({blah: 'text'})) } //custom redirect_url req.query.state
471
+ 'google', { scope : ["email", "profile"] } //custom redirect_url
472
+ // 'google', { scope : ["email", "profile"], callbackURL: req.query.redirect_url } //custom redirect_url
473
+ )(req,res,next);
474
+ });
475
+
476
+ // router.get("/google/callbacks", passport.authenticate("google", { session: false }), (req, res) => {
477
+ // console.log("callback_signup");
478
+ // res.redirect("/google/callback");
479
+ // });
458
480
 
459
481
  // Retrieve user data using the access token received</em>
460
482
  router.get("/google/callback", passport.authenticate("google", { session: false }), (req, res) => {
@@ -462,9 +484,17 @@ router.get("/google/callback", passport.authenticate("google", { session: false
462
484
 
463
485
  var user = req.user;
464
486
  winston.debug("user", user);
487
+ // winston.info("req._toParam: "+ req._toParam);
488
+ // winston.info("req.query.redirect_url: "+ req.query.redirect_url);
489
+ // winston.info("req.query.state: "+ req.query.state);
490
+ winston.info("req.session.redirect_url: "+ req.session.redirect_url);
491
+
465
492
 
466
493
  var userJson = user.toObject();
467
494
 
495
+ delete userJson.password;
496
+
497
+
468
498
  var signOptions = {
469
499
  issuer: 'https://tiledesk.com',
470
500
  subject: 'user',
@@ -485,8 +515,19 @@ router.get("/google/callback", passport.authenticate("google", { session: false
485
515
  // return the information including token as JSON
486
516
  // res.json(returnObject);
487
517
 
488
- var url = process.env.EMAIL_BASEURL+"?token=JWT "+token;
489
- winston.debug("url: "+ url);
518
+ let dashboard_base_url = process.env.EMAIL_BASEURL || config.baseUrl;
519
+ winston.debug("Google Redirect dashboard_base_url: ", dashboard_base_url);
520
+
521
+ let homeurl = "/#/";
522
+
523
+ if (req.session.redirect_url) {
524
+ homeurl = req.session.redirect_url;
525
+ }
526
+
527
+ var url = dashboard_base_url+homeurl+"?token=JWT "+token;
528
+
529
+
530
+ winston.info("Google Redirect: "+ url);
490
531
 
491
532
  res.redirect(url);
492
533
 
package/routes/faq_kb.js CHANGED
@@ -15,6 +15,7 @@ var configGlobal = require('../config/global');
15
15
  const faq = require('../models/faq');
16
16
  var jwt = require('jsonwebtoken');
17
17
  const uuidv4 = require('uuid/v4');
18
+ var ObjectId = require('mongoose').Types.ObjectId;
18
19
 
19
20
  let chatbot_templates_api_url = process.env.CHATBOT_TEMPLATES_API_URL
20
21
 
@@ -312,6 +313,13 @@ router.put('/:faq_kbid', function (req, res) {
312
313
  update.tags = req.body.tags;
313
314
  }
314
315
 
316
+ if (req.body.trained != undefined) {
317
+ update.trained = req.body.trained;
318
+ }
319
+ // update._id = req.params.faq_kbid;
320
+
321
+ winston.debug("update", update);
322
+ // "$set": req.params.faq_kbid
315
323
 
316
324
  Faq_kb.findByIdAndUpdate(req.params.faq_kbid, update, { new: true, upsert: true }, function (err, updatedFaq_kb) { //TODO add cache_bot_here
317
325
  if (err) {
@@ -324,6 +332,14 @@ router.put('/:faq_kbid', function (req, res) {
324
332
  });
325
333
 
326
334
 
335
+
336
+
337
+
338
+
339
+
340
+
341
+
342
+
327
343
  router.patch('/:faq_kbid/attributes', function (req, res) { //TODO add cache_bot_here
328
344
  var data = req.body;
329
345
 
@@ -927,4 +943,30 @@ router.get('/exportjson/:id_faq_kb', (req, res) => {
927
943
  })
928
944
 
929
945
 
946
+
947
+
948
+ router.post('/:faq_kbid/training', function (req, res) {
949
+
950
+ winston.debug(req.body);
951
+
952
+ var update = {};
953
+ update.trained = true;
954
+ // update._id = req.params.faq_kbid;
955
+
956
+ winston.debug("update", update);
957
+ // "$set": req.params.faq_kbid
958
+
959
+ Faq_kb.findByIdAndUpdate(req.params.faq_kbid, update, { new: true, upsert: true }, function (err, updatedFaq_kb) { //TODO add cache_bot_here
960
+ if (err) {
961
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
962
+ }
963
+
964
+ botEvent.emit('faqbot.update', updatedFaq_kb);
965
+ res.json(updatedFaq_kb);
966
+ });
967
+ });
968
+
969
+
970
+
971
+
930
972
  module.exports = router;
package/routes/images.js CHANGED
@@ -23,7 +23,9 @@ const fileService = new FileGridFsService("images");
23
23
 
24
24
 
25
25
  const fileFilter = (req, file, cb) => {
26
- if (file.mimetype == 'image/jpeg' || file.mimetype == 'image/png' || file.mimetype == 'image/gif'|| file.mimetype == 'image/vnd.microsoft.icon') {
26
+ if (file.mimetype == 'image/jpeg' || file.mimetype == 'image/png'
27
+ || file.mimetype == 'image/gif'|| file.mimetype == 'image/vnd.microsoft.icon'
28
+ || file.mimetype == 'image/webp') {
27
29
  cb(null, true);
28
30
  } else {
29
31
  cb(null, false);
package/routes/lead.js CHANGED
@@ -149,6 +149,56 @@ router.patch('/:leadid/attributes', function (req, res) {
149
149
 
150
150
 
151
151
 
152
+ router.patch('/:leadid/properties', function (req, res) {
153
+ var data = req.body;
154
+
155
+ // TODO use service method
156
+
157
+ Lead.findById(req.params.leadid, function (err, lead) {
158
+ if (err) {
159
+ winston.error('--- > ERROR ', err);
160
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
161
+ }
162
+
163
+ if (!lead) {
164
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
165
+ }
166
+
167
+ if (!lead.properties) {
168
+ winston.debug("empty properties")
169
+ lead.properties = {};
170
+ }
171
+
172
+ winston.debug(" lead properties", lead.properties)
173
+
174
+ Object.keys(data).forEach(function(key) {
175
+ var val = data[key];
176
+ winston.debug("data attributes "+key+" " +val)
177
+ lead.properties[key] = val;
178
+ });
179
+
180
+ winston.debug(" lead properties", lead.properties)
181
+
182
+ // https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object
183
+ lead.markModified('properties');
184
+
185
+ //cacheinvalidation
186
+ lead.save(function (err, savedLead) {
187
+ if (err) {
188
+ winston.error("error saving lead properties",err)
189
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
190
+ }
191
+ winston.verbose(" saved lead properties",savedLead.toObject())
192
+ leadEvent.emit('lead.update', savedLead);
193
+
194
+ res.json(savedLead);
195
+ });
196
+ });
197
+
198
+ });
199
+
200
+
201
+
152
202
  // router.put('/:leadid', function (req, res) {
153
203
  // winston.debug(req.body);
154
204
  // var update = {};
@@ -199,6 +249,7 @@ router.delete('/:leadid/physical', function (req, res) {
199
249
  return res.status(403).send({ success: false, msg: 'Unauthorized.' });
200
250
  }
201
251
 
252
+ // TODO use findByIdAndRemove otherwise lead don't contains label object
202
253
  Lead.remove({ _id: req.params.leadid }, function (err, lead) {
203
254
  if (err) {
204
255
  winston.error('--- > ERROR ', err);
package/routes/project.js CHANGED
@@ -46,6 +46,8 @@ router.put('/:projectid/downgradeplan', [passport.authenticate(['basic', 'jwt'],
46
46
  router.delete('/:projectid/physical', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('owner')], function (req, res) {
47
47
  winston.debug(req.body);
48
48
  // TODO delete also department, faq_kb, faq, group, label, lead, message, project_users, requests, subscription
49
+
50
+ // TODO use findByIdAndRemove otherwise project don't contains label object
49
51
  Project.remove({ _id: req.params.projectid }, function (err, project) {
50
52
  if (err) {
51
53
  winston.error('Error deleting project ', err);
@@ -121,12 +123,18 @@ router.put('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: fa
121
123
  if (req.body["settings.email.templates.newMessage"]!=undefined) {
122
124
  update["settings.email.templates.newMessage"] = req.body["settings.email.templates.newMessage"];
123
125
  }
126
+ if (req.body["settings.email.templates.newMessageFollower"]!=undefined) {
127
+ update["settings.email.templates.newMessageFollower"] = req.body["settings.email.templates.newMessageFollower"];
128
+ }
124
129
  if (req.body["settings.email.templates.ticket"]!=undefined) {
125
130
  update["settings.email.templates.ticket"] = req.body["settings.email.templates.ticket"];
126
131
  }
127
132
  if (req.body["settings.email.templates.sendTranscript"]!=undefined) {
128
133
  update["settings.email.templates.sendTranscript"] = req.body["settings.email.templates.sendTranscript"];
129
134
  }
135
+ if (req.body["settings.email.templates.emailDirect"]!=undefined) {
136
+ update["settings.email.templates.emailDirect"] = req.body["settings.email.templates.emailDirect"];
137
+ }
130
138
 
131
139
 
132
140
  if (req.body["settings.email.from"]!=undefined) {
@@ -512,6 +520,8 @@ router.get('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: fa
512
520
  winston.warn('Project not found ');
513
521
  return res.status(404).send({ success: false, msg: 'Object not found.' });
514
522
  }
523
+
524
+ //TODO REMOVE settings from project
515
525
  res.json(project);
516
526
  });
517
527
  });
@@ -608,6 +618,8 @@ router.get('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
608
618
 
609
619
  project_users.sort((a, b) => (a.id_project && b.id_project && a.id_project.updatedAt > b.id_project.updatedAt) ? 1 : -1)
610
620
  project_users.reverse();
621
+
622
+ //TODO REMOVE settings from project
611
623
  res.json(project_users);
612
624
  });
613
625
  });