@chat21/chat21-ionic 3.4.24 → 3.4.26-rc1

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
@@ -8,6 +8,14 @@
8
8
  ### **Copyrigth**:
9
9
  *Tiledesk SRL*
10
10
 
11
+ # 3.4.26-rc1
12
+ - **added**: tiledesk_projectID query param to manage user status
13
+ - **added**: token to managane ticket feature
14
+ - **added**: getOsCode login into utils.ts
15
+
16
+ # 3.4.25 in PROD
17
+ - **changed**: pipe marked to support malicious text input
18
+
11
19
  # 3.4.24 in PROD
12
20
  - **changed**: fullname in info message replaced with firstname
13
21
 
@@ -26,6 +34,24 @@
26
34
  # 3.4.22 in PROD
27
35
  - **added**: managed allowed_upload_extentions from project settings
28
36
 
37
+ # 3.4.21-rc6
38
+ - **added**: managed allowed_upload_extentions from project settings
39
+
40
+ # 3.4.21-rc5
41
+ - **added**: setConversation as read when agent click on it
42
+
43
+ # 3.4.21-rc4
44
+ - **added**: ability to init and decrement new conversation count badge
45
+
46
+ # 3.4.21-rc3
47
+ - **changed**: badge notification for agentDesktop
48
+
49
+ # 3.4.21-rc2
50
+ - **added**: count in newConversation handler event
51
+
52
+ # 3.4.21-rc1
53
+ - **added**: implement badge notification for agentDesktop sw when new conversation is assigned to logged agent
54
+
29
55
  # 3.4.21 in PROD
30
56
 
31
57
  # 3.4.20 in PROD
package/angular.json CHANGED
@@ -26,6 +26,7 @@
26
26
  "src/chat-config-mqtt-localhost.json",
27
27
  "src/chat-config-native-mqtt.json",
28
28
  "src/chat-config-native-prod.json",
29
+ "src/chat-config-native-stage.json",
29
30
  "src/firebase-messaging-sw.js",
30
31
  "src/manifest.json",
31
32
  "src/chat-config-template.json",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-ionic",
3
3
  "author": "Tiledesk SRL",
4
- "version": "3.4.24",
4
+ "version": "3.4.26-rc1",
5
5
  "license": "MIT License",
6
6
  "homepage": "https://tiledesk.com/",
7
7
  "repository": {
@@ -168,6 +168,7 @@ export class AppComponent implements OnInit {
168
168
  }, { capture: true });
169
169
  }
170
170
 
171
+
171
172
  listenChatAlreadyOpenWithoutParamsInMobileMode() {
172
173
  this.events.subscribe('noparams:mobile', (isAlreadyOpenInMobileMode) => {
173
174
  // console.log('[APP-COMP] Chat is Already Open In Mobile Mode ', isAlreadyOpenInMobileMode)
@@ -332,7 +333,7 @@ export class AppComponent implements OnInit {
332
333
 
333
334
  listenToPostMsgs() {
334
335
  window.addEventListener("message", (event) => {
335
- this.logger.log("[APP-COMP] message event ", event);
336
+ // this.logger.log("[APP-COMP] message event ", event);
336
337
 
337
338
  if (event && event.data && event.data.action && event.data.parameter) {
338
339
  if (event.data.action === 'openJoinConversationModal') {
@@ -1110,6 +1111,7 @@ export class AppComponent implements OnInit {
1110
1111
  if (conversation && conversation.is_new === true && this.isInitialized) {
1111
1112
  this.manageTabNotification('conv_added', conversation.sound)
1112
1113
  this.manageEventNewConversation(conversation)
1114
+ this.setNotification();
1113
1115
  }
1114
1116
  if(conversation) this.updateConversationsOnStorage()
1115
1117
  });
@@ -1193,6 +1195,7 @@ export class AppComponent implements OnInit {
1193
1195
  this.initArchivedConversationsHandler(currentUser.uid);
1194
1196
  this.segmentSignIn()
1195
1197
  }
1198
+
1196
1199
  this.checkPlatform();
1197
1200
  try {
1198
1201
  this.logger.debug('[APP-COMP] ************** closeModal', this.authModal);
@@ -1343,7 +1346,10 @@ export class AppComponent implements OnInit {
1343
1346
 
1344
1347
  subscribeConversationSelected= (conversation: ConversationModel) => {
1345
1348
  if(conversation && conversation.is_new){
1346
- this.audio_NewConv.pause()
1349
+ this.audio_NewConv.pause();
1350
+ this.conversationsHandlerService.setConversationRead(conversation.uid)
1351
+ //UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
1352
+ this.setNotification();
1347
1353
  }
1348
1354
  }
1349
1355
 
@@ -1419,6 +1425,9 @@ export class AppComponent implements OnInit {
1419
1425
  this.logger.debug('[APP-COMP]-CONVS - INIT CONV CONVS 2', conversations)
1420
1426
  this.events.publish('appcompSubscribeToConvs:loadingIsActive', false);
1421
1427
  }
1428
+
1429
+ //INIT NOTIFICATION FOR NEW CONVERSATION COUNT
1430
+ this.setNotification();
1422
1431
  });
1423
1432
 
1424
1433
  }
@@ -1635,6 +1644,14 @@ export class AppComponent implements OnInit {
1635
1644
  this.triggerEvents.triggerOnNewConversationInit(conversation)
1636
1645
  }
1637
1646
 
1647
+ private setNotification() {
1648
+ this.logger.log('[APP-COMP] setNotification for NEW CONVERSATION');
1649
+ if(window['AGENTDESKTOP']){
1650
+ this.logger.log('[APP-COMP] manageNotification AGENTDESKTOP exist', window['AGENTDESKTOP']);
1651
+ window['AGENTDESKTOP']['TAB'].Badge(this.conversationsHandlerService.countIsNew().toString())
1652
+ }
1653
+ }
1654
+
1638
1655
 
1639
1656
  @HostListener('document:visibilitychange', [])
1640
1657
  visibilitychange() {
@@ -94,11 +94,6 @@
94
94
  <!-- openInfoConversation {{openInfoConversation}} -->
95
95
  <ion-buttons slot="end" *ngIf="isMobile">
96
96
 
97
- <!-- <ion-button ion-button fill="clear" color="primary" size="small" (click)="presentCreateTicketModal()" [ngClass]="{'resolve-conv-margin-right': !isMobile}">
98
- <ion-icon name="ticket-outline"></ion-icon>
99
- <span style="text-transform: capitalize; margin-left: 5px;"> {{ 'Crea ticket' | translate}} </span>
100
- </ion-button> -->
101
-
102
97
  <!-- <ion-button *ngIf="conversationUid?.startsWith('support-group') && conv_type !== 'archived'" ion-button fill="clear" size="small"
103
98
  (click)="closeConversation()" [disabled]="conv_closed === true">
104
99
  <ion-icon name="archive-outline"></ion-icon>
@@ -14,9 +14,7 @@ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service
14
14
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'
15
15
  import { Platform } from '@ionic/angular'
16
16
 
17
- import { ModalController } from '@ionic/angular'
18
17
  import { EventsService } from 'src/app/services/events-service'
19
- import { CreateTicketPage } from 'src/app/modals/create-ticket/create-ticket.page'
20
18
  import { TiledeskService } from 'src/app/services/tiledesk/tiledesk.service'
21
19
  import { CHANNEL_TYPE } from 'src/chat21-core/utils/constants'
22
20
  import { isOnMobileDevice } from 'src/chat21-core/utils/utils';
@@ -132,24 +130,5 @@ export class HeaderConversationDetailComponent implements OnInit, OnChanges {
132
130
  this.openInfoConversation = !this.openInfoConversation
133
131
  this.onOpenInfoConversation.emit(this.openInfoConversation)
134
132
  }
135
-
136
- // -----------------------------------------------------------------
137
- // PRESENT MODAL CREATE TICKET (MOVED IN ddp-deader.component.ts)
138
- // -----------------------------------------------------------------
139
- // async presentCreateTicketModal(e: any): Promise<any>{
140
-
141
- // // const attributes = { enableBackdropDismiss: false };
142
- // const modal: HTMLIonModalElement =
143
- // await this.modalController.create({
144
- // component: CreateTicketPage,
145
- // // componentProps: attributes,
146
- // swipeToClose: false,
147
- // backdropDismiss: false
148
- // });
149
- // modal.onDidDismiss().then((detail: any) => {
150
- // this.logger.log('[CONVS-DETAIL][HEADER] ', detail.data);
151
- // });
152
- // return await modal.present();
153
- // }
154
133
  }
155
134
 
@@ -22,7 +22,7 @@
22
22
  </ion-buttons>
23
23
 
24
24
  <ion-buttons slot="end">
25
- <ion-button *ngIf="!isMobile && supportMode" ion-button fill="clear" (click)="presentCreateTicketModal()"
25
+ <ion-button *ngIf="!isMobile && supportMode && isVisibleTKT" ion-button fill="clear" (click)="presentCreateTicketModal()"
26
26
  tooltip="{{translationMap?.get('CreateTicket')}}" placement="bottom">
27
27
  <ion-icon slot="icon-only" name="ticket-outline"></ion-icon>
28
28
  </ion-button>
@@ -16,6 +16,7 @@ export class HeaderConversationsList implements OnInit {
16
16
  @Input() writeto_btn: boolean
17
17
  @Input() sound_btn: string;
18
18
  @Input() isMobile: boolean;
19
+ @Input() isVisibleTKT: boolean = true;
19
20
  @Output() onSoundChange = new EventEmitter<string>()
20
21
  @Output() openContactsDirectory = new EventEmitter()
21
22
  @Output() openProfileInfo = new EventEmitter()
@@ -84,23 +85,6 @@ export class HeaderConversationsList implements OnInit {
84
85
  this.events.publish('profileInfoButtonClick:changed', 'displayArchived')
85
86
  }
86
87
 
87
- // PRESENT MODAL CREATE TICKET
88
- // async presentCreateTicketModal(): Promise<any>{
89
-
90
- // // const attributes = { enableBackdropDismiss: false };
91
- // const modal: HTMLIonModalElement =
92
- // await this.modalController.create({
93
- // component: CreateTicketPage,
94
- // // componentProps: attributes,
95
- // swipeToClose: false,
96
- // backdropDismiss: false
97
- // });
98
- // modal.onDidDismiss().then((detail: any) => {
99
- // console.log('[DDP-HEADER] ', detail.data);
100
- // });
101
- // return await modal.present();
102
- // }
103
-
104
88
  async presentCreateTicketModal() {
105
89
  // const attributes = { enableBackdropDismiss: false };
106
90
  const modal = await this.modalController.create({
@@ -1,6 +1,6 @@
1
1
  import { ConversationModel } from 'src/chat21-core/models/conversation';
2
2
  import { EventsService } from './../../services/events-service';
3
- import { Component, EventEmitter, HostListener, OnInit, Output } from '@angular/core';
3
+ import { Component, EventEmitter, HostListener, Input, OnInit, Output } from '@angular/core';
4
4
  import { WebsocketService } from 'src/app/services/websocket/websocket.service';
5
5
  import { Subject } from 'rxjs';
6
6
  import { takeUntil, skip } from 'rxjs/operators';
@@ -24,6 +24,7 @@ import { ProjectService } from 'src/app/services/projects/project.service';
24
24
  export class ProjectItemComponent implements OnInit {
25
25
  private logger: LoggerService = LoggerInstance.getInstance();
26
26
 
27
+ @Input() projectID: string;
27
28
  @Output() projectIdEvent = new EventEmitter<string>()
28
29
  @Output() openUnsevedConvsEvent = new EventEmitter<any>()
29
30
 
@@ -180,8 +181,21 @@ export class ProjectItemComponent implements OnInit {
180
181
 
181
182
  this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS - RES this.project', this.project);
182
183
 
183
- localStorage.setItem('last_project', JSON.stringify(projects[0]))
184
+ if(this.projectID){
185
+ const project = projects.find(prjct => prjct.id_project._id === this.projectID)
186
+ if(project){
187
+ this.project = project
188
+ this.logger.log('[PROJECT-ITEM] - GET PROJECTS - project found with this.projectID', this.project);
189
+ localStorage.setItem('last_project', JSON.stringify(this.project))
190
+ this.doProjectSubscriptions(this.project)
191
+ return
192
+ }else{
193
+ this.logger.log('[PROJECT-ITEM] - GET PROJECTS - project NOT found with this.projectID', this.projectID);
194
+ }
195
+ }
196
+
184
197
  if (projects[0]) {
198
+ localStorage.setItem('last_project', JSON.stringify(projects[0]))
185
199
  this.project = projects[0];
186
200
  this.doProjectSubscriptions(this.project)
187
201
  }
@@ -15,6 +15,7 @@ import { tranlatedLanguage } from '../../../chat21-core/utils/constants';
15
15
  // utils
16
16
  import { avatarPlaceholder, getColorBck } from 'src/chat21-core/utils/utils-user';
17
17
  import { BRAND_BASE_INFO, LOGOS_ITEMS } from 'src/app/utils/utils-resources';
18
+ import { getOSCode } from 'src/app/utils/utils';
18
19
 
19
20
  @Component({
20
21
  selector: 'app-sidebar',
@@ -267,103 +268,14 @@ export class SidebarComponent implements OnInit {
267
268
 
268
269
  getOSCODE() {
269
270
  this.public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK;
270
- this.logger.log('[SIDEBAR] AppConfigService getAppConfig public_Key', this.public_Key);
271
-
272
- if (this.public_Key) {
273
- let keys = this.public_Key.split("-");
274
- this.logger.log('[SIDEBAR] PUBLIC-KEY - public_Key keys', keys)
275
-
276
- keys.forEach(key => {
277
-
278
- if (key.includes("ANA")) {
279
-
280
- let ana = key.split(":");
281
-
282
- if (ana[1] === "F") {
283
- this.isVisibleANA = false;
284
- } else {
285
- this.isVisibleANA = true;
286
- }
287
- }
288
-
289
- if (key.includes("ACT")) {
290
- let act = key.split(":");
291
- if (act[1] === "F") {
292
- this.isVisibleACT = false;
293
- } else {
294
- this.isVisibleACT = true;
295
- }
296
- }
297
-
298
- if (key.includes("APP")) {
299
- let lbs = key.split(":");
300
- if (lbs[1] === "F") {
301
- this.isVisibleAPP = false;
302
- } else {
303
- this.isVisibleAPP = true;
304
- }
305
- }
306
-
307
- if (key.includes("MON")) {
308
- let lbs = key.split(":");
309
- if (lbs[1] === "F") {
310
- this.isVisibleMON = false;
311
- } else {
312
- this.isVisibleMON = true;
313
- }
314
- }
315
-
316
- if (key.includes("CNT")) {
317
- let lbs = key.split(":");
318
- if (lbs[1] === "F") {
319
- this.isVisibleCNT = false;
320
- } else {
321
- this.isVisibleCNT = true;
322
- }
323
- }
324
-
325
- if (key.includes("KNB")) {
326
- let lbs = key.split(":");
327
- if (lbs[1] === "F") {
328
- this.isVisibleKNB = false;
329
- } else {
330
- this.isVisibleKNB = true;
331
- }
332
- }
333
-
334
- });
335
-
336
-
337
- if (!this.public_Key.includes("ANA")) {
338
- this.isVisibleANA = false;
339
- }
340
- if (!this.public_Key.includes("ACT")) {
341
- this.isVisibleACT = false;
342
- }
343
- if (!this.public_Key.includes("APP")) {
344
- this.isVisibleAPP = false;
345
- }
346
- if (!this.public_Key.includes("MON")) {
347
- this.isVisibleMON = false;
348
- }
349
- if (!this.public_Key.includes("CNT")) {
350
- this.isVisibleCNT = false;
351
- }
352
-
353
- if (!this.public_Key.includes("KNB")) {
354
- this.isVisibleKNB = false;
355
- }
356
-
357
- } else {
358
- this.isVisibleANA = false;
359
- this.isVisibleACT = false;
360
- this.isVisibleAPP = false;
361
- this.isVisibleMON = false;
362
- this.isVisibleCNT = false;
363
- this.isVisibleKNB = false;
364
- }
365
-
366
-
271
+
272
+ this.isVisibleANA = getOSCode("ANA", this.public_Key);
273
+ this.isVisibleACT = getOSCode("ACT", this.public_Key);
274
+ this.isVisibleAPP = getOSCode("APP", this.public_Key);
275
+ this.isVisibleMON = getOSCode("MON", this.public_Key);
276
+ this.isVisibleCNT = getOSCode("CNT", this.public_Key);
277
+ this.isVisibleKNB = getOSCode("KNB", this.public_Key);
278
+
367
279
  }
368
280
 
369
281
  listenTocurrentProjectUserUserAvailability$() {
@@ -15,6 +15,7 @@ import { avatarPlaceholder, getColorBck } from 'src/chat21-core/utils/utils-user
15
15
  import { environment } from 'src/environments/environment';
16
16
  import { Project } from 'src/chat21-core/models/projects';
17
17
  import { BRAND_BASE_INFO } from 'src/app/utils/utils-resources';
18
+ import { getOSCode } from 'src/app/utils/utils';
18
19
  @Component({
19
20
  selector: 'app-sidebar-user-details',
20
21
  templateUrl: './sidebar-user-details.component.html',
@@ -253,29 +254,8 @@ export class SidebarUserDetailsComponent implements OnInit, OnChanges {
253
254
  this.public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK;
254
255
  this.logger.log('[SIDEBAR-USER-DETAILS] AppConfigService getAppConfig public_Key', this.public_Key);
255
256
  this.logger.log('[SIDEBAR-USER-DETAILS] AppConfigService getAppConfig', this.appConfigProvider.getConfig());
256
- if (this.public_Key) {
257
- let keys = this.public_Key.split("-");
258
- this.logger.log('[SIDEBAR-USER-DETAILS] PUBLIC-KEY - public_Key keys', keys)
259
-
260
- keys.forEach(key => {
261
- if (key.includes("PAY")) {
262
-
263
- let pay = key.split(":");
264
-
265
- if (pay[1] === "F") {
266
- this.isVisiblePAY = false;
267
- } else {
268
- this.isVisiblePAY = true;
269
- }
270
- }
271
- });
272
-
273
- if (!this.public_Key.includes("PAY")) {
274
- this.isVisiblePAY = false;
275
- }
276
- } else {
277
- this.isVisiblePAY = false;
278
- }
257
+
258
+ this.isVisiblePAY = getOSCode("PAY", this.public_Key);
279
259
  }
280
260
 
281
261
  listenToCurrentStoredProject() {
@@ -1,6 +1,7 @@
1
1
  import { Pipe, PipeTransform } from '@angular/core';
2
2
  import { marked } from 'marked';
3
3
 
4
+
4
5
  @Pipe({
5
6
  name: 'marked'
6
7
  })
@@ -8,19 +9,78 @@ import { marked } from 'marked';
8
9
  export class MarkedPipe implements PipeTransform {
9
10
  transform(value: any): any {
10
11
  const renderer = new marked.Renderer();
11
- renderer.link = function(href, title, text) {
12
- const link = marked.Renderer.prototype.link.call(this, href, title, text);
13
- return link.replace('<a', '<a target="_blank" ');
12
+ renderer.link = function (href, title, text) {
13
+ // Normalizza l'href per evitare falsi negativi
14
+ const normalized = (href || '').trim().toLowerCase();
15
+ // Pattern pericolosi da cercare nell'intero URL (non solo all'inizio)
16
+ const dangerousPatterns = [
17
+ /javascript:/i, // javascript: protocol
18
+ /data:/i, // data: protocol
19
+ /vbscript:/i, // vbscript: protocol
20
+ /on\w+\s*=/i, // event handlers (onclick, onload, etc.)
21
+ /alert\s*\(/i, // alert() function
22
+ /eval\s*\(/i, // eval() function
23
+ /document\./i, // document object access
24
+ /window\./i, // window object access
25
+ /\.appendChild\s*\(/i, // DOM manipulation
26
+ /\.createElement\s*\(/i, // DOM creation
27
+ /<script/i, // script tags
28
+ /<\/script>/i, // closing script tags
29
+ /function\s*\(/i, // function definitions
30
+ /\(function/i, // IIFE patterns
31
+ /setTimeout\s*\(/i, // setTimeout
32
+ /setInterval\s*\(/i, // setInterval
33
+ /location\./i, // location object manipulation
34
+ /history\./i, // history object manipulation
35
+ /localStorage\./i, // localStorage access
36
+ /sessionStorage\./i, // sessionStorage access
37
+ /cookie/i, // cookie manipulation
38
+ /fetch\s*\(/i, // fetch API
39
+ /XMLHttpRequest/i, // XHR
40
+ /FormData/i, // FormData
41
+ /Blob\s*\(/i, // Blob constructor
42
+ /FileReader/i, // FileReader
43
+ /crypto\./i, // crypto object
44
+ /btoa\s*\(/i, // base64 encoding
45
+ /atob\s*\(/i, // base64 decoding
46
+ /decodeURI/i, // URI decoding
47
+ /encodeURI/i, // URI encoding
48
+ /String\.fromCharCode/i, // character code conversion
49
+ /unescape\s*\(/i, // unescape function
50
+ /escape\s*\(/i // escape function
51
+ ];
52
+
53
+ // Controlla se l'URL contiene pattern pericolosi
54
+ const isDangerous = dangerousPatterns.some(p => p.test(normalized));
55
+ if (isDangerous) {
56
+ // Se l’URL è pericoloso, restituisci solo il testo
57
+ return text || href || '';
58
+ }
59
+
60
+ // tokens = this.cleanInput(href);
61
+
62
+ if (!href) return text;
63
+
64
+ return `<a href="${href}" target="_blank" rel="noopener noreferrer">${text}</a>`;
14
65
  };
66
+
15
67
  marked.setOptions({
16
- renderer: renderer
68
+ renderer,
69
+ gfm: true,
70
+ breaks: true
17
71
  });
72
+
18
73
  if (value && value.length > 0) {
19
- const text = marked(value);
20
- return text;
74
+ try {
75
+ return marked.parse(value);
76
+ } catch (err) {
77
+ console.error('Errore nel parsing markdown:', err);
78
+ return value;
79
+ }
21
80
  }
22
81
  return value;
23
82
  }
24
83
 
25
84
 
85
+
26
86
  }
@@ -83,6 +83,7 @@ import { WebsocketService } from 'src/app/services/websocket/websocket.service';
83
83
  import { Project } from 'src/chat21-core/models/projects';
84
84
  import { Globals } from 'src/app/utils/globals';
85
85
  import { ProjectService } from 'src/app/services/projects/project.service';
86
+ import { getOSCode } from 'src/app/utils/utils';
86
87
 
87
88
  @Component({
88
89
  selector: 'app-conversation-detail',
@@ -266,6 +267,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
266
267
 
267
268
  this.getConversations();
268
269
  this.watchToConnectionStatus();
270
+ this.supportMode = this.g.supportMode;
269
271
  this.getOSCODE();
270
272
  this.listenToEventServiceEvents();
271
273
  this.listenToDsbrdPostMsgs();
@@ -374,35 +376,9 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
374
376
  }
375
377
 
376
378
  getOSCODE() {
377
- this.supportMode = this.g.supportMode;
378
- this.logger.log('[CONVS-DETAIL] AppConfigService getAppConfig supportMode', this.supportMode)
379
379
  this.public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK
380
380
  this.logger.log('[CONVS-DETAIL] AppConfigService getAppConfig public_Key', this.public_Key)
381
-
382
- if (this.public_Key) {
383
- let keys = this.public_Key.split('-')
384
- this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - public_Key keys', keys)
385
-
386
- keys.forEach((key) => {
387
- if (key.includes('CAR')) {
388
- let car = key.split(':')
389
- if (car[1] === 'F') {
390
- this.areVisibleCAR = false
391
- this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - areVisibleCAR', this.areVisibleCAR)
392
- } else {
393
- this.areVisibleCAR = true
394
- this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - areVisibleCAR', this.areVisibleCAR)
395
- }
396
- }
397
- })
398
-
399
- if (!this.public_Key.includes('CAR')) {
400
- this.areVisibleCAR = false
401
- this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - areVisibleCAR', this.areVisibleCAR)
402
- }
403
- } else {
404
- this.areVisibleCAR = false
405
- }
381
+ this.areVisibleCAR = getOSCode("CAR", this.public_Key);
406
382
  }
407
383
 
408
384
  watchToConnectionStatus() {
@@ -6,6 +6,7 @@
6
6
  [writeto_btn]="writeto_btn"
7
7
  [sound_btn]="sound_btn"
8
8
  [isMobile]="isMobile"
9
+ [isVisibleTKT]="isVisibleTKT"
9
10
  (onSoundChange)="onSoundChange($event)"
10
11
  (openContactsDirectory)=openContactsDirectory($event)
11
12
  (openProfileInfo)=openProfileInfo($event)>
@@ -39,6 +40,7 @@
39
40
  </ion-note> -->
40
41
 
41
42
  <app-project-item
43
+ [projectID]="g?.projectID"
42
44
  (openUnsevedConvsEvent)="openUnsevedConversationIframe($event)"
43
45
  (projectIdEvent)="getLastProjectId($event)">
44
46
  </app-project-item>
@@ -53,6 +53,7 @@ import { Globals } from 'src/app/utils/globals';
53
53
  import { TriggerEvents } from 'src/app/services/triggerEvents/triggerEvents';
54
54
  import { MessageModel } from 'src/chat21-core/models/message';
55
55
  import { Project } from 'src/chat21-core/models/projects';
56
+ import { getOSCode } from 'src/app/utils/utils';
56
57
 
57
58
  @Component({
58
59
  selector: 'app-conversations-list',
@@ -80,6 +81,7 @@ export class ConversationListPage implements OnInit {
80
81
  public writeto_btn: boolean
81
82
  public archived_btn: boolean
82
83
  public sound_btn: string
84
+ public isVisibleTKT: boolean = true;
83
85
  public convertMessage = convertMessage
84
86
  private isShowMenuPage = false
85
87
  private logger: LoggerService = LoggerInstance.getInstance()
@@ -131,7 +133,7 @@ export class ConversationListPage implements OnInit {
131
133
  public appConfigProvider: AppConfigProvider,
132
134
  public platform: Platform,
133
135
  public wsService: WebsocketService,
134
- private g: Globals,
136
+ public g: Globals,
135
137
  ) {
136
138
  this.checkPlatform();
137
139
  this.translations();
@@ -206,7 +208,7 @@ export class ConversationListPage implements OnInit {
206
208
  // -----------------------------------------------
207
209
  ngOnInit() {
208
210
  this.getAppConfigToHideDiplayBtns()
209
-
211
+ this.getOSCODE();
210
212
  }
211
213
 
212
214
  ngOnChanges() {
@@ -234,7 +236,6 @@ export class ConversationListPage implements OnInit {
234
236
  this.sound_btn = 'enabled'
235
237
  }
236
238
 
237
-
238
239
  }
239
240
 
240
241
  ionViewWillEnter() {
@@ -626,6 +627,12 @@ export class ConversationListPage implements OnInit {
626
627
  }
627
628
  }
628
629
 
630
+ getOSCODE() {
631
+ const public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK
632
+ this.logger.log('[CONVS-LIST-PAGE] AppConfigService getAppConfig public_Key', public_Key)
633
+ this.isVisibleTKT = getOSCode("TKT", public_Key);
634
+ }
635
+
629
636
  onBackButtonFN(event) {
630
637
  this.conversationType = 'active'
631
638
 
@@ -23,6 +23,7 @@ import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'
23
23
  import { WebsocketService } from 'src/app/services/websocket/websocket.service';
24
24
  import { checkPlatformIsMobile, setLastDateWithLabels } from 'src/chat21-core/utils/utils';
25
25
  import { Project } from 'src/chat21-core/models/projects';
26
+ import { getOSCode } from 'src/app/utils/utils';
26
27
 
27
28
  @Component({
28
29
  selector: 'app-profile-info',
@@ -264,30 +265,7 @@ export class ProfileInfoPage implements OnInit {
264
265
  getOSCODE() {
265
266
  let public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK;
266
267
  this.logger.log('[PROFILE-INFO-PAGE] AppConfigService getAppConfig public_Key', public_Key);
267
- this.logger.log('[PROFILE-INFO-PAGE] AppConfigService getAppConfig', this.appConfigProvider.getConfig());
268
- if (public_Key) {
269
- let keys = public_Key.split("-");
270
- this.logger.log('[PROFILE-INFO-PAGE] PUBLIC-KEY - public_Key keys', keys)
271
-
272
- keys.forEach(key => {
273
- if (key.includes("PAY")) {
274
-
275
- let pay = key.split(":");
276
-
277
- if (pay[1] === "F") {
278
- this.isVisiblePAY = false;
279
- } else {
280
- this.isVisiblePAY = true;
281
- }
282
- }
283
- });
284
-
285
- if (!public_Key.includes("PAY")) {
286
- this.isVisiblePAY = false;
287
- }
288
- } else {
289
- this.isVisiblePAY = false;
290
- }
268
+ this.isVisiblePAY = getOSCode("PAY", public_Key);
291
269
  }
292
270
 
293
271
  copyLoggedUserUID() {
@@ -135,5 +135,10 @@ export class GlobalSettingsService {
135
135
  globals.logLevel = TEMP;
136
136
  }
137
137
 
138
+ TEMP = getParameterByName(windowContext, 'tiledesk_projectID');
139
+ if (TEMP) {
140
+ globals.projectID = TEMP;
141
+ }
142
+
138
143
  }
139
144
  }
@@ -14,6 +14,7 @@ export class Globals {
14
14
  lang: string;
15
15
  jwt: string;
16
16
  fileUploadAccept: string;
17
+ projectID: string;
17
18
 
18
19
  constructor(
19
20
  ) { }
@@ -34,6 +35,7 @@ export class Globals {
34
35
  this.persistence = 'local';
35
36
  this.lang = 'en'
36
37
  this.fileUploadAccept = 'image/*,.pdf,.txt'
38
+ this.projectID = null;
37
39
 
38
40
  }
39
41
 
@@ -0,0 +1,24 @@
1
+ export function getOSCode(key: string, token: string): boolean {
2
+
3
+ if (token) {
4
+ const keys: String[] = token.split("-");
5
+
6
+ let element = keys.find(el => el.includes(key))
7
+ console.log('keys', keys)
8
+ if(element){
9
+ element = element.split(":")[1]
10
+ if(element && element === "F"){
11
+ return false
12
+ } else {
13
+ return true
14
+ }
15
+ }
16
+
17
+ if (!token.includes(key)) {
18
+ return false;
19
+ }
20
+
21
+ }
22
+
23
+ return false
24
+ }
@@ -975,7 +975,10 @@ export function isEmoji(str: string) {
975
975
 
976
976
  export function isAllowedUrlInText(text: string, allowedUrls: string[]) {
977
977
  const urlsInMessage = extractUrls(text);
978
- console.log('urlsInMessage ++++ :', urlsInMessage);
978
+
979
+ if (urlsInMessage.length === 0) {
980
+ return true; // Nessun URL => testo ammesso
981
+ }
979
982
 
980
983
  const allowedPatterns = allowedUrls.map((url) => {
981
984
  try {
@@ -990,6 +993,9 @@ export function isAllowedUrlInText(text: string, allowedUrls: string[]) {
990
993
 
991
994
  const matchesAllowed = (domain: string) => {
992
995
  return allowedPatterns.some((pattern) => {
996
+ if (pattern === '*') {
997
+ return true; //accept all
998
+ }
993
999
  if (pattern.startsWith('*.')) {
994
1000
  const base = pattern.replace(/^\*\./, '');
995
1001
  return domain === base || domain.endsWith('.' + base);