Skip to content
This repository was archived by the owner on Nov 5, 2025. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 45 additions & 27 deletions src/server/bridges/LivechatBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,111 +12,129 @@ import { AppPermissions } from '../permissions/AppPermissions';

import { BaseBridge } from './BaseBridge';

type LivechatReadPermissions = keyof Pick<
typeof AppPermissions,
'livechat-department' |
'livechat-message' |
'livechat-room' |
'livechat-status' |
'livechat-visitor'
>;

type LivechatWritePermissions = keyof Pick<
typeof AppPermissions,
'livechat-custom-fields' |
'livechat-department' |
'livechat-message' |
'livechat-room' |
'livechat-visitor'
>;

export abstract class LivechatBridge extends BaseBridge {
public doIsOnline(departmentId?: string, appId?: string): boolean {
if (this.hasReadPermission(appId, 'status')) {
if (this.hasReadPermission(appId, 'livechat-status')) {
return this.isOnline(departmentId, appId);
}
}

public async doIsOnlineAsync(departmentId?: string, appId?: string): Promise<boolean> {
if (this.hasReadPermission(appId, 'status')) {
if (this.hasReadPermission(appId, 'livechat-status')) {
return this.isOnlineAsync(departmentId, appId);
}
}

public async doCreateMessage(message: ILivechatMessage, appId: string): Promise<string> {
if (this.hasWritePermission(appId, 'message')) {
if (this.hasWritePermission(appId, 'livechat-message')) {
return this.createMessage(message, appId);
}
}

public async doGetMessageById(messageId: string, appId: string): Promise<ILivechatMessage> {
if (this.hasReadPermission(appId, 'message')) {
if (this.hasReadPermission(appId, 'livechat-message')) {
return this.getMessageById(messageId, appId);
}
}

public async doUpdateMessage(message: ILivechatMessage, appId: string): Promise<void> {
if (this.hasWritePermission(appId, 'message')) {
if (this.hasWritePermission(appId, 'livechat-message')) {
return this.updateMessage(message, appId);
}
}

public async doCreateVisitor(visitor: IVisitor, appId: string): Promise<string> {
if (this.hasWritePermission(appId, 'visitor')) {
if (this.hasWritePermission(appId, 'livechat-visitor')) {
return this.createVisitor(visitor, appId);
}
}

public async doFindVisitors(query: object, appId: string): Promise<Array<IVisitor>> {
if (this.hasReadPermission(appId, 'visitor')) {
if (this.hasReadPermission(appId, 'livechat-visitor')) {
return this.findVisitors(query, appId);
}
}

public async doFindVisitorById(id: string, appId: string): Promise<IVisitor | undefined> {
if (this.hasReadPermission(appId, 'visitor')) {
if (this.hasReadPermission(appId, 'livechat-visitor')) {
return this.findVisitorById(id, appId);
}
}

public async doFindVisitorByEmail(email: string, appId: string): Promise<IVisitor | undefined> {
if (this.hasReadPermission(appId, 'visitor')) {
if (this.hasReadPermission(appId, 'livechat-visitor')) {
return this.findVisitorByEmail(email, appId);
}
}

public async doFindVisitorByToken(token: string, appId: string): Promise<IVisitor | undefined> {
if (this.hasReadPermission(appId, 'visitor')) {
if (this.hasReadPermission(appId, 'livechat-visitor')) {
return this.findVisitorByToken(token, appId);
}
}

public async doFindVisitorByPhoneNumber(phoneNumber: string, appId: string): Promise<IVisitor | undefined> {
if (this.hasReadPermission(appId, 'visitor')) {
if (this.hasReadPermission(appId, 'livechat-visitor')) {
return this.findVisitorByPhoneNumber(phoneNumber, appId);
}
}

public async doTransferVisitor(visitor: IVisitor, transferData: ILivechatTransferData, appId: string): Promise<boolean> {
if (this.hasWritePermission(appId, 'visitor')) {
if (this.hasWritePermission(appId, 'livechat-visitor')) {
return this.transferVisitor(visitor, transferData, appId);
}
}

public async doCreateRoom(visitor: IVisitor, agent: IUser, appId: string): Promise<ILivechatRoom> {
if (this.hasWritePermission(appId, 'room')) {
if (this.hasWritePermission(appId, 'livechat-room')) {
return this.createRoom(visitor, agent, appId);
}
}

public async doCloseRoom(room: ILivechatRoom, comment: string, appId: string): Promise<boolean> {
if (this.hasWritePermission(appId, 'room')) {
if (this.hasWritePermission(appId, 'livechat-room')) {
return this.closeRoom(room, comment, appId);
}
}

public async doFindRooms(visitor: IVisitor, departmentId: string | null, appId: string): Promise<Array<ILivechatRoom>> {
if (this.hasReadPermission(appId, 'room')) {
if (this.hasReadPermission(appId, 'livechat-room')) {
return this.findRooms(visitor, departmentId, appId);
}
}

public async doFindDepartmentByIdOrName(value: string, appId: string): Promise<IDepartment | undefined> {
if (this.hasReadPermission(appId, 'department') && this.hasMultiplePermission(appId, 'department')) {
if (this.hasReadPermission(appId, 'livechat-department') && this.hasMultiplePermission(appId)) {
return this.findDepartmentByIdOrName(value, appId);
}
}

public async doFindDepartmentsEnabledWithAgents(appId: string): Promise<Array<IDepartment>> {
if (this.hasMultiplePermission(appId, 'department')) {
if (this.hasMultiplePermission(appId)) {
return this.findDepartmentsEnabledWithAgents(appId);
}
}

public async doSetCustomFields(data: { token: IVisitor['token']; key: string; value: string; overwrite: boolean }, appId: string): Promise<number> {
if (this.hasWritePermission(appId, 'custom-fields')) {
if (this.hasWritePermission(appId, 'livechat-custom-fields')) {
return this.setCustomFields(data, appId);
}
}
Expand Down Expand Up @@ -150,40 +168,40 @@ export abstract class LivechatBridge extends BaseBridge {

protected abstract setCustomFields(data: { token: IVisitor['token']; key: string; value: string; overwrite: boolean }, appId: string): Promise<number>;

private hasReadPermission(appId: string, feature: string): boolean {
if (!AppPermissionManager.hasPermission(appId, (AppPermissions as any)[`livechat-${ feature }`].read)) {
private hasReadPermission(appId: string, scope: LivechatReadPermissions): boolean {
if (AppPermissionManager.hasPermission(appId, AppPermissions[scope].read)) {
return true;
}

AppPermissionManager.notifyAboutError(new PermissionDeniedError({
appId,
missingPermissions: [(AppPermissions as any)[`livechat-${ feature }`].read],
missingPermissions: [AppPermissions[scope].read],
}));

return false;
}

private hasWritePermission(appId: string, feature: string): boolean {
if (!AppPermissionManager.hasPermission(appId, (AppPermissions as any)[`livechat-${ feature }`].write)) {
private hasWritePermission(appId: string, scope: LivechatWritePermissions): boolean {
if (AppPermissionManager.hasPermission(appId, AppPermissions[scope].write)) {
return true;
}

AppPermissionManager.notifyAboutError(new PermissionDeniedError({
appId,
missingPermissions: [(AppPermissions as any)[`livechat-${ feature }`].write],
missingPermissions: [AppPermissions[scope].write],
}));

return false;
}

private hasMultiplePermission(appId: string, feature: string): boolean {
if (!AppPermissionManager.hasPermission(appId, (AppPermissions as any)[`livechat-${ feature }`].multiple)) {
private hasMultiplePermission(appId: string): boolean {
if (AppPermissionManager.hasPermission(appId, AppPermissions['livechat-department'].multiple)) {
return true;
}

AppPermissionManager.notifyAboutError(new PermissionDeniedError({
appId,
missingPermissions: [(AppPermissions as any)[`livechat-${ feature }`].multiple],
missingPermissions: [AppPermissions['livechat-department'].multiple],
}));

return false;
Expand Down