chore!: remove old voip permissions (#37672)

This commit is contained in:
Pierre Lehnen 2025-12-09 14:01:36 -03:00 committed by Guilherme Gazzo
parent be4c300038
commit ac11ea05ff
21 changed files with 73 additions and 119 deletions

View File

@ -0,0 +1,6 @@
---
'@rocket.chat/i18n': major
'@rocket.chat/meteor': major
---
Removes deprecated VoIP permissions

View File

@ -0,0 +1,16 @@
---
'@rocket.chat/model-typings': major
'@rocket.chat/core-typings': major
'@rocket.chat/rest-typings': major
'@rocket.chat/ui-contexts': major
'@rocket.chat/ui-voip': major
'@rocket.chat/models': major
'@rocket.chat/i18n': major
'@rocket.chat/meteor': major
'@rocket.chat/apps-engine': minor
'@rocket.chat/core-services': minor
'@rocket.chat/message-types': minor
'@rocket.chat/ddp-client': minor
---
Removes deprecated VoIP from Omnichannel

View File

@ -0,0 +1,11 @@
---
'@rocket.chat/model-typings': major
'@rocket.chat/core-typings': major
'@rocket.chat/rest-typings': major
'@rocket.chat/models': major
'@rocket.chat/i18n': major
'@rocket.chat/meteor': major
'@rocket.chat/core-services': minor
---
Removes Deprecated FreeSwitch integration

View File

@ -169,7 +169,6 @@ export async function findPaginatedUsersByStatus({
}
const canSeeAllUserInfo = await hasPermissionAsync(uid, 'view-full-other-user-info');
const canSeeExtension = canSeeAllUserInfo || (await hasPermissionAsync(uid, 'view-user-voip-extension'));
const projection = {
name: 1,
@ -183,7 +182,7 @@ export async function findPaginatedUsersByStatus({
type: 1,
reason: 1,
federated: 1,
...(canSeeExtension ? { freeSwitchExtension: 1 } : {}),
freeSwitchExtension: 1,
};
if (searchTerm?.trim()) {

View File

@ -22,7 +22,7 @@ import { openRoom } from '../../../../server/lib/openRoom';
import { createDirectMessage } from '../../../../server/methods/createDirectMessage';
import { hideRoomMethod } from '../../../../server/methods/hideRoom';
import { canAccessRoomIdAsync } from '../../../authorization/server/functions/canAccessRoom';
import { hasAtLeastOnePermissionAsync, hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { saveRoomSettings } from '../../../channel-settings/server/methods/saveRoomSettings';
import { getRoomByNameOrIdWithOptionToJoin } from '../../../lib/server/functions/getRoomByNameOrIdWithOptionToJoin';
import { getChannelHistory } from '../../../lib/server/methods/getChannelHistory';
@ -385,12 +385,6 @@ API.v1.addRoute(
...(status && { status: { $in: status } }),
};
const canSeeExtension = await hasAtLeastOnePermissionAsync(
this.userId,
['view-full-other-user-info', 'view-user-voip-extension'],
room._id,
);
const options: FindOptions<IUser> = {
projection: {
_id: 1,
@ -400,7 +394,7 @@ API.v1.addRoute(
statusText: 1,
utcOffset: 1,
federated: 1,
...(canSeeExtension && { freeSwitchExtension: 1 }),
freeSwitchExtension: 1,
},
skip: offset,
limit: count,

View File

@ -326,7 +326,7 @@ API.v1.addRoute(
validateCustomFields(this.bodyParams.customFields);
}
if (this.bodyParams.freeSwitchExtension && !(await canEditExtension(this.userId, this.bodyParams.freeSwitchExtension))) {
if (this.bodyParams.freeSwitchExtension && !(await canEditExtension(this.bodyParams.freeSwitchExtension))) {
return API.v1.failure('Setting user voice call extension is not allowed', 'error-action-not-allowed');
}

View File

@ -211,13 +211,6 @@ export const permissions = [
{ _id: 'remove-closed-livechat-room', roles: ['livechat-manager', 'admin'] },
{ _id: 'remove-livechat-department', roles: ['livechat-manager', 'admin'] },
// Allow managing team collab voip extensions
{ _id: 'manage-voip-extensions', roles: ['admin'] },
// Allow viewing the extension number of other users
{ _id: 'view-user-voip-extension', roles: ['admin', 'user'] },
// Allow viewing details of an extension
{ _id: 'view-voip-extension-details', roles: ['admin', 'user'] },
// New Media calls permissions
{ _id: 'allow-internal-voice-calls', roles: ['admin', 'user'] },
{ _id: 'allow-external-voice-calls', roles: ['admin', 'user'] },

View File

@ -22,6 +22,7 @@ export const defaultFields = {
federated: 1,
statusLivechat: 1,
abacAttributes: 1,
freeSwitchExtension: 1,
} as const;
export const fullFields = {
@ -35,7 +36,6 @@ export const fullFields = {
requirePasswordChangeReason: 1,
roles: 1,
importIds: 1,
freeSwitchExtension: 1,
} as const;
let publicCustomFields: Record<string, 0 | 1> = {};
@ -86,7 +86,6 @@ export async function getFullUserDataByIdOrUsernameOrImportId(
(searchType === 'username' && searchValue === caller.username) ||
(searchType === 'importId' && caller.importIds?.includes(searchValue));
const canViewAllInfo = !!myself || (await hasPermissionAsync(userId, 'view-full-other-user-info'));
const canViewExtension = !!myself || (await hasPermissionAsync(userId, 'view-user-voip-extension'));
// Only search for importId if the user has permission to view the import id
if (searchType === 'importId' && !canViewAllInfo) {
@ -98,7 +97,6 @@ export async function getFullUserDataByIdOrUsernameOrImportId(
const options = {
projection: {
...fields,
...(canViewExtension && { freeSwitchExtension: 1 }),
...(myself && { services: 1 }),
},
};

View File

@ -12,15 +12,11 @@ const isEditingUserRoles = (previousRoles: IUser['roles'], newRoles?: IUser['rol
(newRoles.some((item) => !previousRoles.includes(item)) || previousRoles.some((item) => !newRoles.includes(item)));
const isEditingField = (previousValue?: string, newValue?: string) => typeof newValue !== 'undefined' && newValue !== previousValue;
export const canEditExtension = async (userId: string, newExtension?: string) => {
export const canEditExtension = async (newExtension?: string) => {
if (!settings.get('VoIP_TeamCollab_Enabled')) {
return false;
}
if (!(await hasPermissionAsync(userId, 'manage-voip-extensions'))) {
return false;
}
if (newExtension && (await Users.findOneByFreeSwitchExtension(newExtension, { projection: { _id: 1 } }))) {
throw new MeteorError('error-extension-not-available', 'Extension is already assigned to another user');
}
@ -117,7 +113,7 @@ export async function validateUserEditing(userId: IUser['_id'], userData: Update
if (
isEditingField(user.freeSwitchExtension ?? '', userData.freeSwitchExtension) &&
!(await canEditExtension(userId, userData.freeSwitchExtension))
!(await canEditExtension(userData.freeSwitchExtension))
) {
throw new MeteorError('error-action-not-allowed', 'Edit user voice call extension is not allowed', {
method: 'insertOrUpdateUser',

View File

@ -38,7 +38,7 @@ import AdminUserSetRandomPasswordContent from './AdminUserSetRandomPasswordConte
import AdminUserSetRandomPasswordRadios from './AdminUserSetRandomPasswordRadios';
import PasswordFieldSkeleton from './PasswordFieldSkeleton';
import { useSmtpQuery } from './hooks/useSmtpQuery';
import { useVoipExtensionPermission } from './useVoipExtensionPermission';
import { useShowVoipExtension } from './useShowVoipExtension';
import { parseCSV } from '../../../../lib/utils/parseCSV';
import UserAvatarEditor from '../../../components/avatar/UserAvatarEditor';
import { useEndpointMutation } from '../../../hooks/useEndpointMutation';
@ -123,7 +123,7 @@ const AdminUserForm = ({ userData, onReload, context, refetchUserFormData, roleD
mode: 'onBlur',
});
const canManageVoipExtension = useVoipExtensionPermission();
const showVoipExtension = useShowVoipExtension();
const { avatar, username, setRandomPassword, password, name: userFullName } = watch();
@ -341,7 +341,7 @@ const AdminUserForm = ({ userData, onReload, context, refetchUserFormData, roleD
</FieldError>
)}
</Field>
{canManageVoipExtension && (
{showVoipExtension && (
<Field>
<FieldLabel htmlFor={voiceExtensionId}>{t('Voice_call_extension')}</FieldLabel>
<FieldRow>

View File

@ -20,7 +20,7 @@ import UsersTableFilters from './UsersTableFilters';
import UsersTableRow from './UsersTableRow';
import GenericNoResults from '../../../../components/GenericNoResults';
import type { AdminUsersTab, UsersFilters, UsersTableSortingOption } from '../AdminUsersPage';
import { useVoipExtensionPermission } from '../useVoipExtensionPermission';
import { useShowVoipExtension } from '../useShowVoipExtension';
type UsersTableProps = {
tab: AdminUsersTab;
@ -58,7 +58,7 @@ const UsersTable = ({
const isMobile = !breakpoints.includes('xl');
const isLaptop = !breakpoints.includes('xxl');
const canManageVoipExtension = useVoipExtensionPermission();
const showVoipExtension = useShowVoipExtension();
const { current, itemsPerPage, setCurrent, setItemsPerPage, ...paginationProps } = paginationData;
const isKeyboardEvent = (event: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>): event is KeyboardEvent<HTMLElement> => {
@ -137,7 +137,7 @@ const UsersTable = ({
{t('Pending_action')}
</GenericTableHeaderCell>
),
tab === 'all' && canManageVoipExtension && (
tab === 'all' && showVoipExtension && (
<GenericTableHeaderCell
w='x180'
key='freeSwitchExtension'
@ -153,7 +153,7 @@ const UsersTable = ({
{t('Actions')}
</GenericTableHeaderCell>,
],
[sortData, t, isLaptop, tab, isMobile, canManageVoipExtension],
[sortData, t, isLaptop, tab, isMobile, showVoipExtension],
);
return (
@ -195,7 +195,7 @@ const UsersTable = ({
isMobile={isMobile}
isLaptop={isLaptop}
isSeatsCapExceeded={isSeatsCapExceeded}
showVoipExtension={canManageVoipExtension}
showVoipExtension={showVoipExtension}
onReload={onReload}
onClick={handleClickOrKeyDown}
/>

View File

@ -0,0 +1,7 @@
import { useSetting } from '@rocket.chat/ui-contexts';
export const useShowVoipExtension = () => {
const isVoipSettingEnabled = useSetting('VoIP_TeamCollab_Enabled', false);
return isVoipSettingEnabled;
};

View File

@ -1,8 +0,0 @@
import { useSetting, usePermission } from '@rocket.chat/ui-contexts';
export const useVoipExtensionPermission = () => {
const isVoipSettingEnabled = useSetting('VoIP_TeamCollab_Enabled', false);
const canManageVoipExtensions = usePermission('manage-voip-extensions');
return isVoipSettingEnabled && canManageVoipExtensions;
};

View File

@ -33,5 +33,6 @@ import './v324';
import './v325';
import './v326';
import './v327';
import './v328';
export * from './xrun';

View File

@ -0,0 +1,15 @@
import { Permissions } from '@rocket.chat/models';
import { addMigration } from '../../lib/migrations';
addMigration({
version: 328,
name: 'Remove Old Voip Permissions',
async up() {
await Permissions.deleteMany({
_id: {
$in: ['manage-voip-extensions', 'view-user-voip-extension', 'view-voip-extension-details'],
},
});
},
});

View File

@ -580,12 +580,10 @@ describe('[Users]', () => {
(IS_EE ? describe : describe.skip)('Voice call extension', () => {
beforeEach(async () => {
await updateSetting('VoIP_TeamCollab_Enabled', true);
await updatePermission('manage-voip-extensions', ['admin']);
});
after(async () => {
await updateSetting('VoIP_TeamCollab_Enabled', true);
await updatePermission('manage-voip-extensions', ['admin']);
});
it('should create a user with a voice call extension', async () => {
@ -668,30 +666,6 @@ describe('[Users]', () => {
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
});
});
it('should not create a user if user has no permission to manage voip extensions', async () => {
await updatePermission('manage-voip-extensions', []);
await request
.post(api('users.create'))
.set(credentials)
.send({
email: 'fail_no_permission@rocket.chat',
name: 'fail_no_permission',
username: 'fail_no_permission',
password,
active: true,
roles: ['user'],
joinDefaultChannels: true,
verified: true,
freeSwitchExtension: '999',
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-action-not-allowed');
});
});
});
describe('default email2fa auto opt in configuration', () => {
@ -2556,15 +2530,11 @@ describe('[Users]', () => {
});
after(async () => {
await Promise.all([
deleteUser(user),
updateSetting('VoIP_TeamCollab_Enabled', true),
updatePermission('manage-voip-extensions', ['admin']),
]);
await Promise.all([deleteUser(user), updateSetting('VoIP_TeamCollab_Enabled', true)]);
});
beforeEach(async () => {
await Promise.all([updatePermission('manage-voip-extensions', ['admin']), updateSetting('VoIP_TeamCollab_Enabled', true)]);
await Promise.all([updateSetting('VoIP_TeamCollab_Enabled', true)]);
});
it("should update the user's voice call extension", async () => {
@ -2601,20 +2571,6 @@ describe('[Users]', () => {
});
});
it("should not update the user's voice call extension if the user has no permission to manage voip extensions", async () => {
await updatePermission('manage-voip-extensions', []);
await request
.post(api('users.update'))
.set(credentials)
.send({
userId: user._id,
data: {
freeSwitchExtension: '9998',
},
})
.expect(400);
});
it("should not update the user's voice call extension if voip setting is disabled", async () => {
await updateSetting('VoIP_TeamCollab_Enabled', false);
await request

View File

@ -6478,8 +6478,6 @@
"manage-the-app": "Manage the App",
"manage-user-status": "Manage User Status",
"manage-user-status_description": "Permission to manage the server custom user statuses",
"manage-voip-extensions": "Manage Voice Calls",
"manage-voip-extensions_description": "Permission to manage voice calls and assign extensions to users",
"marketplace_featured_section_community_featured": "Featured Community Apps",
"marketplace_featured_section_community_supported": "Community Supported Apps",
"marketplace_featured_section_enterprise": "Featured Enterprise Apps",
@ -7020,10 +7018,6 @@
"view-statistics_description": "Permission to view system statistics such as number of users logged in, number of rooms, operating system information",
"view-user-administration": "View User Administration",
"view-user-administration_description": "Permission to partial, read-only list view of other user accounts currently logged into the system. No user account information is accessible with this permission",
"view-user-voip-extension": "Allow Voice Calls",
"view-user-voip-extension_description": "Permission to allow users to use the voice call feature",
"view-voip-extension-details": "View Voice Call Extensions",
"view-voip-extension-details_description": "Permission to view which user is calling and their extension info",
"webdav-account-saved": "WebDAV account saved",
"webdav-account-updated": "WebDAV account updated",
"webdav-server-not-found": "WebDAV server not found",

View File

@ -6313,8 +6313,6 @@
"manage-the-app": "Administrer appen",
"manage-user-status": "Administrer brukerstatus",
"manage-user-status_description": "Tillatelse til å administrere serverens egendefinerte brukerstatuser",
"manage-voip-extensions": "Administrer taleanrop",
"manage-voip-extensions_description": "Tillatelse til å administrere taleanrop og tildele utvidelser til brukere",
"marketplace_featured_section_community_featured": "Utvalgte fellesskapsapper",
"marketplace_featured_section_community_supported": "Apper som støttes av fellesskapet",
"marketplace_featured_section_enterprise": "Utvalgte bedriftsapper",
@ -6854,10 +6852,6 @@
"view-statistics_description": "Tillatelse til å se systemstatistikk som antall brukere pålogget, antall rom, operativsysteminformasjon",
"view-user-administration": "Se brukeradministrasjon",
"view-user-administration_description": "Tillatelse til delvis, skrivebeskyttet listevisning av andre brukerkontoer som for øyeblikket er logget på systemet. Ingen brukerkontoinformasjon er tilgjengelig med denne tillatelsen",
"view-user-voip-extension": "Tillat taleanrop",
"view-user-voip-extension_description": "Tillatelse til å la brukere bruke taleanropsfunksjonen",
"view-voip-extension-details": "Se taleanropsutvidelser",
"view-voip-extension-details_description": "Tillatelse til å se hvilken bruker som ringer og deres internnummer",
"webdav-account-saved": "WebDAV-konto lagret",
"webdav-account-updated": "WebDAV-konto oppdatert",
"webdav-server-not-found": "WebDAV-server ble ikke funnet",

View File

@ -5748,8 +5748,6 @@
"manage-the-app": "Administrer appen",
"manage-user-status": "Administrer brukerstatus",
"manage-user-status_description": "Tillatelse til å administrere serverens egendefinerte brukerstatuser",
"manage-voip-extensions": "Administrer taleanrop",
"manage-voip-extensions_description": "Tillatelse til å administrere taleanrop og tildele utvidelser til brukere",
"marketplace_featured_section_community_featured": "Utvalgte fellesskapsapper",
"marketplace_featured_section_community_supported": "Apper som støttes av fellesskapet",
"marketplace_featured_section_enterprise": "Utvalgte bedriftsapper",
@ -6094,10 +6092,6 @@
"view-statistics_description": "Tillatelse til å vise systemstatistikk som antall brukere logget inn, antall rom, operativsysteminformasjon",
"view-user-administration": "Se Brukeradministrasjon",
"view-user-administration_description": "Tillatelse til delvis, skrivebeskyttet listevisning av andre brukerkontoer som for øyeblikket er logget inn i systemet. Ingen brukerkontoinformasjon er tilgjengelig med denne tillatelsen",
"view-user-voip-extension": "Tillat taleanrop",
"view-user-voip-extension_description": "Tillatelse til å la brukere bruke taleanropsfunksjonen",
"view-voip-extension-details": "Se taleanropsutvidelser",
"view-voip-extension-details_description": "Tillatelse til å se hvilken bruker som ringer og deres internnummer",
"webdav-server-not-found": "WebDAV-server ble ikke funnet",
"will_be_able_to": "vil kunne",
"yesterday": "i går",

View File

@ -6179,8 +6179,6 @@
"manage-the-app": "Gerencie o aplicativo",
"manage-user-status": "Gerenciar status do usuário",
"manage-user-status_description": "Permissão para gerenciar status de usuário personalizado do servidor",
"manage-voip-extensions": "Gerenciar chamadas de voz",
"manage-voip-extensions_description": "Permissão para gerenciar chamadas de voz e atribuir ramais aos usuários",
"marketplace_featured_section_community_featured": "Aplicativos da comunidade em destaque",
"marketplace_featured_section_community_supported": "Aplicativos com suporte da comunidade",
"marketplace_featured_section_enterprise": "Aplicativos Enterprise em destaque",
@ -6716,10 +6714,6 @@
"view-statistics_description": "Permissão para visualizar as estatísticas do sistema, como número de usuários logados, número de salas, informações do sistema operacional",
"view-user-administration": "Ver administração do usuário",
"view-user-administration_description": "Permissão para exibição de lista parcial, somente de leitura, de outras contas de usuário atualmente conectados no sistema. Nenhuma informação da conta do usuário é acessível com esta permissão",
"view-user-voip-extension": "Permitir chamadas de voz",
"view-user-voip-extension_description": "Permissão para permitir que os usuários usem o recurso de chamada de voz",
"view-voip-extension-details": "Exibir ramais de chamadas de voz",
"view-voip-extension-details_description": "Permissão para visualizar o usuário que está ligando e as informações do ramal",
"webdav-account-saved": "Conta WebDAV salva",
"webdav-account-updated": "Conta WebDAV atualizada",
"webdav-server-not-found": "Servidor WebDAV não encontrado",

View File

@ -6220,8 +6220,6 @@
"manage-the-app": "Hantera appen",
"manage-user-status": "Hantera användarstatus",
"manage-user-status_description": "Behörighet att hantera anpassade användarstatusar för servern",
"manage-voip-extensions": "Hantera röstsamtal",
"manage-voip-extensions_description": "Behörighet att hantera röstsamtal och tilldela anknytningar till användare",
"marketplace_featured_section_community_featured": "Utvalda communityappar",
"marketplace_featured_section_community_supported": "Appar som stöds av communityn",
"marketplace_featured_section_enterprise": "Utvalda Enterprise-sappar",
@ -6756,10 +6754,6 @@
"view-statistics_description": "Tillstånd att visa systemstatistik som antal användare inloggade, antal rum, operativsystemsinformation",
"view-user-administration": "Visa användaradministration",
"view-user-administration_description": "Tillstånd till delvis, skrivskyddad listvy över andra användarkonton som för närvarande är inloggade i systemet. Ingen användarkontoinformation är tillgänglig med detta tillstånd",
"view-user-voip-extension": "Tillåt röstsamtal",
"view-user-voip-extension_description": "Tillstånd att tillåta användare att använda röstsamtalsfunktionen",
"view-voip-extension-details": "Visa anknytningar för röstsamtal",
"view-voip-extension-details_description": "Behörighet att se vilken användare som ringer och deras anknytningsinformation",
"webdav-account-saved": "WebDAV-kontot har sparats",
"webdav-account-updated": "WebDAV-kontot har uppdaterats",
"webdav-server-not-found": "WebDAV-servern hittades inte",