@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 +26 -0
- package/angular.json +1 -0
- package/package.json +1 -1
- package/src/app/app.component.ts +19 -2
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.html +0 -5
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.ts +0 -21
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.html +1 -1
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.ts +1 -17
- package/src/app/components/project-item/project-item.component.ts +16 -2
- package/src/app/components/sidebar/sidebar.component.ts +9 -97
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +3 -23
- package/src/app/directives/marked.pipe.ts +66 -6
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +3 -27
- package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
- package/src/app/pages/conversations-list/conversations-list.page.ts +10 -3
- package/src/app/pages/profile-info/profile-info.page.ts +2 -24
- package/src/app/services/global-settings/global-settings.service.ts +5 -0
- package/src/app/utils/globals.ts +2 -0
- package/src/app/utils/utils.ts +24 -0
- package/src/chat21-core/utils/utils.ts +7 -1
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
package/package.json
CHANGED
package/src/app/app.component.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
-
|
|
257
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
68
|
+
renderer,
|
|
69
|
+
gfm: true,
|
|
70
|
+
breaks: true
|
|
17
71
|
});
|
|
72
|
+
|
|
18
73
|
if (value && value.length > 0) {
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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.
|
|
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() {
|
package/src/app/utils/globals.ts
CHANGED
|
@@ -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
|
-
|
|
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);
|