-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: block contact channel (#33590)
* feat: add new block contact channel endpoint * chore: eslint fix * fix: module name * fix: remove module from license package * feat: close room for blocked contacts * feat: throw an error if contact is blocked * refactor: move typings to ee * fix: closes the room as the agent * chore: register the api endpoints * feat: add permissions * test: ensure that blocking feature is working as intende * fix: forbid creation of rooms if contact is blocked * test: increase coverage * fix: remove Meteor usage * refactor: make update easier to read * fix: check if license has the right module * fix: remove empty line * fix: remove _id from projection * refactor: return a promise to avoid waiting twice * updated code to new data format * lints --------- Co-authored-by: Matheus Barbosa Silva <[email protected]> Co-authored-by: Pierre <[email protected]>
- Loading branch information
1 parent
e8444c0
commit b47fb3c
Showing
13 changed files
with
369 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
apps/meteor/ee/app/livechat-enterprise/server/api/contacts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import Ajv from 'ajv'; | ||
|
||
import { API } from '../../../../../app/api/server'; | ||
import { changeContactBlockStatus, closeBlockedRoom, ensureSingleContactLicense } from './lib/contacts'; | ||
|
||
const ajv = new Ajv({ | ||
coerceTypes: true, | ||
}); | ||
|
||
type blockContactProps = { | ||
visitorId: string; | ||
}; | ||
|
||
const blockContactSchema = { | ||
type: 'object', | ||
properties: { | ||
contactId: { | ||
type: 'string', | ||
}, | ||
visitorId: { | ||
type: 'string', | ||
}, | ||
}, | ||
required: ['contactId', 'visitorId'], | ||
additionalProperties: false, | ||
}; | ||
|
||
const isBlockContactProps = ajv.compile<blockContactProps>(blockContactSchema); | ||
|
||
declare module '@rocket.chat/rest-typings' { | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
interface Endpoints { | ||
'/v1/omnichannel/contacts.block': { | ||
POST: (params: blockContactProps) => void; | ||
}; | ||
'/v1/omnichannel/contacts.unblock': { | ||
POST: (params: blockContactProps) => void; | ||
}; | ||
} | ||
} | ||
|
||
API.v1.addRoute( | ||
'omnichannel/contacts.block', | ||
{ | ||
authRequired: true, | ||
permissionsRequired: ['block-livechat-contact'], | ||
validateParams: isBlockContactProps, | ||
}, | ||
{ | ||
async post() { | ||
ensureSingleContactLicense(); | ||
const { visitorId } = this.bodyParams; | ||
const { user } = this; | ||
|
||
await changeContactBlockStatus({ | ||
visitorId, | ||
block: true, | ||
}); | ||
|
||
await closeBlockedRoom(visitorId, user); | ||
|
||
return API.v1.success(); | ||
}, | ||
}, | ||
); | ||
|
||
API.v1.addRoute( | ||
'omnichannel/contacts.unblock', | ||
{ | ||
authRequired: true, | ||
permissionsRequired: ['unblock-livechat-contact'], | ||
validateParams: isBlockContactProps, | ||
}, | ||
{ | ||
async post() { | ||
ensureSingleContactLicense(); | ||
const { visitorId } = this.bodyParams; | ||
|
||
await changeContactBlockStatus({ | ||
visitorId, | ||
block: false, | ||
}); | ||
|
||
return API.v1.success(); | ||
}, | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,4 @@ import './rooms'; | |
import './transcript'; | ||
import './reports'; | ||
import './triggers'; | ||
import './contacts'; |
36 changes: 36 additions & 0 deletions
36
apps/meteor/ee/app/livechat-enterprise/server/api/lib/contacts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import type { IUser } from '@rocket.chat/core-typings'; | ||
import { License } from '@rocket.chat/license'; | ||
import { LivechatContacts, LivechatRooms, LivechatVisitors } from '@rocket.chat/models'; | ||
|
||
import { Livechat } from '../../../../../../app/livechat/server/lib/LivechatTyped'; | ||
import { i18n } from '../../../../../../server/lib/i18n'; | ||
|
||
export async function changeContactBlockStatus({ block, visitorId }: { visitorId: string; block: boolean }) { | ||
const result = await LivechatContacts.updateContactChannel(visitorId, { blocked: block }); | ||
|
||
if (!result.modifiedCount) { | ||
throw new Error('error-contact-not-found'); | ||
} | ||
} | ||
|
||
export function ensureSingleContactLicense() { | ||
if (!License.hasModule('contact-id-verification')) { | ||
throw new Error('error-action-not-allowed'); | ||
} | ||
} | ||
|
||
export async function closeBlockedRoom(visitorId: string, user: IUser) { | ||
const visitor = await LivechatVisitors.findOneById(visitorId); | ||
|
||
if (!visitor) { | ||
throw new Error('error-visitor-not-found'); | ||
} | ||
|
||
const room = await LivechatRooms.findOneOpenByVisitorToken(visitor.token); | ||
|
||
if (!room) { | ||
return; | ||
} | ||
|
||
return Livechat.closeRoom({ room, visitor, comment: i18n.t('close-blocked-room-comment'), user }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.