-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4afd41c
commit 1056f22
Showing
10 changed files
with
293 additions
and
18 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@rocket.chat/meteor": patch | ||
"@rocket.chat/i18n": patch | ||
--- | ||
|
||
Prevent usage of OTR messages with End-to-end Encryption, both feature shouldn't and can't work together. |
122 changes: 122 additions & 0 deletions
122
apps/meteor/client/hooks/roomActions/useE2EERoomAction.spec.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,122 @@ | ||
import { useSetting, usePermission, useEndpoint } from '@rocket.chat/ui-contexts'; | ||
import { act, renderHook } from '@testing-library/react-hooks'; | ||
|
||
import { E2EEState } from '../../../app/e2e/client/E2EEState'; | ||
import { e2e } from '../../../app/e2e/client/rocketchat.e2e'; | ||
import { OtrRoomState } from '../../../app/otr/lib/OtrRoomState'; | ||
import { dispatchToastMessage } from '../../lib/toast'; | ||
import { useRoom, useRoomSubscription } from '../../views/room/contexts/RoomContext'; | ||
import { useE2EEState } from '../../views/room/hooks/useE2EEState'; | ||
import { useOTR } from '../useOTR'; | ||
import { useE2EERoomAction } from './useE2EERoomAction'; | ||
|
||
jest.mock('@rocket.chat/ui-contexts', () => ({ | ||
useSetting: jest.fn(), | ||
usePermission: jest.fn(), | ||
useEndpoint: jest.fn(), | ||
})); | ||
|
||
jest.mock('../../lib/toast', () => ({ | ||
dispatchToastMessage: jest.fn(), | ||
})); | ||
|
||
jest.mock('../../views/room/contexts/RoomContext', () => ({ | ||
useRoom: jest.fn(), | ||
useRoomSubscription: jest.fn(), | ||
})); | ||
|
||
jest.mock('../useOTR', () => ({ | ||
useOTR: jest.fn(), | ||
})); | ||
|
||
jest.mock('../../../app/e2e/client/rocketchat.e2e', () => ({ | ||
e2e: { | ||
isReady: jest.fn(), | ||
}, | ||
})); | ||
|
||
jest.mock('../../views/room/hooks/useE2EEState', () => ({ | ||
useE2EEState: jest.fn(), | ||
})); | ||
|
||
jest.mock('react-i18next', () => ({ | ||
useTranslation: () => ({ | ||
t: (key: string) => key, | ||
}), | ||
})); | ||
|
||
jest.mock('meteor/tracker', () => ({ | ||
Tracker: { | ||
autorun: jest.fn(), | ||
}, | ||
})); | ||
|
||
describe('useE2EERoomAction', () => { | ||
const mockRoom = { _id: 'roomId', encrypted: false, t: 'd', name: 'Test Room' }; | ||
const mockSubscription = { autoTranslate: false }; | ||
|
||
beforeEach(() => { | ||
(useSetting as jest.Mock).mockReturnValue(true); | ||
(useRoom as jest.Mock).mockReturnValue(mockRoom); | ||
(useRoomSubscription as jest.Mock).mockReturnValue(mockSubscription); | ||
(useE2EEState as jest.Mock).mockReturnValue(E2EEState.READY); | ||
(usePermission as jest.Mock).mockReturnValue(true); | ||
(useEndpoint as jest.Mock).mockReturnValue(jest.fn().mockResolvedValue({ success: true })); | ||
(e2e.isReady as jest.Mock).mockReturnValue(true); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should dispatch error toast message when otrState is ESTABLISHED', async () => { | ||
(useOTR as jest.Mock).mockReturnValue({ otrState: OtrRoomState.ESTABLISHED }); | ||
|
||
const { result } = renderHook(() => useE2EERoomAction()); | ||
|
||
await act(async () => { | ||
await result?.current?.action?.(); | ||
}); | ||
|
||
expect(dispatchToastMessage).toHaveBeenCalledWith({ type: 'error', message: 'E2EE_not_available_OTR' }); | ||
}); | ||
|
||
it('should dispatch error toast message when otrState is ESTABLISHING', async () => { | ||
(useOTR as jest.Mock).mockReturnValue({ otrState: OtrRoomState.ESTABLISHING }); | ||
|
||
const { result } = renderHook(() => useE2EERoomAction()); | ||
|
||
await act(async () => { | ||
await result?.current?.action?.(); | ||
}); | ||
|
||
expect(dispatchToastMessage).toHaveBeenCalledWith({ type: 'error', message: 'E2EE_not_available_OTR' }); | ||
}); | ||
|
||
it('should dispatch error toast message when otrState is REQUESTED', async () => { | ||
(useOTR as jest.Mock).mockReturnValue({ otrState: OtrRoomState.REQUESTED }); | ||
|
||
const { result } = renderHook(() => useE2EERoomAction()); | ||
|
||
await act(async () => { | ||
await result?.current?.action?.(); | ||
}); | ||
|
||
expect(dispatchToastMessage).toHaveBeenCalledWith({ type: 'error', message: 'E2EE_not_available_OTR' }); | ||
}); | ||
|
||
it('should dispatch success toast message when encryption is enabled', async () => { | ||
(useOTR as jest.Mock).mockReturnValue({ otrState: OtrRoomState.NOT_STARTED }); | ||
|
||
const { result } = renderHook(() => useE2EERoomAction()); | ||
|
||
await act(async () => { | ||
await result?.current?.action?.(); | ||
}); | ||
|
||
expect(dispatchToastMessage).toHaveBeenCalledWith({ | ||
type: 'success', | ||
message: 'E2E_Encryption_enabled_for_room', | ||
}); | ||
}); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { useUserId } from '@rocket.chat/ui-contexts'; | ||
import { renderHook } from '@testing-library/react-hooks'; | ||
|
||
import OTR from '../../app/otr/client/OTR'; | ||
import { OtrRoomState } from '../../app/otr/lib/OtrRoomState'; | ||
import { useRoom } from '../views/room/contexts/RoomContext'; | ||
import { useOTR } from './useOTR'; | ||
|
||
jest.mock('@rocket.chat/ui-contexts', () => ({ | ||
useUserId: jest.fn(), | ||
})); | ||
|
||
jest.mock('../views/room/contexts/RoomContext', () => ({ | ||
useRoom: jest.fn(), | ||
})); | ||
|
||
jest.mock('../../app/otr/client/OTR', () => ({ | ||
getInstanceByRoomId: jest.fn(), | ||
})); | ||
|
||
jest.mock('./useReactiveValue', () => ({ | ||
useReactiveValue: jest.fn((fn) => fn()), | ||
})); | ||
|
||
describe('useOTR', () => { | ||
it('should return error state when user ID is not available', () => { | ||
(useUserId as jest.Mock).mockReturnValue(undefined); | ||
(useRoom as jest.Mock).mockReturnValue({ _id: 'roomId' }); | ||
|
||
const { result } = renderHook(() => useOTR()); | ||
|
||
expect(result.current.otr).toBeUndefined(); | ||
expect(result.current.otrState).toBe(OtrRoomState.ERROR); | ||
}); | ||
|
||
it('should return error state when room ID is not available', () => { | ||
(useUserId as jest.Mock).mockReturnValue('userId'); | ||
(useRoom as jest.Mock).mockReturnValue(undefined); | ||
|
||
const { result } = renderHook(() => useOTR()); | ||
|
||
expect(result.current.otr).toBeUndefined(); | ||
expect(result.current.otrState).toBe(OtrRoomState.ERROR); | ||
}); | ||
|
||
it('should return error state when OTR instance is not available', () => { | ||
(useUserId as jest.Mock).mockReturnValue('userId'); | ||
(useRoom as jest.Mock).mockReturnValue({ _id: 'roomId' }); | ||
(OTR.getInstanceByRoomId as jest.Mock).mockReturnValue(undefined); | ||
|
||
const { result } = renderHook(() => useOTR()); | ||
|
||
expect(result.current.otr).toBeUndefined(); | ||
expect(result.current.otrState).toBe(OtrRoomState.ERROR); | ||
}); | ||
|
||
it('should return the correct OTR instance and state when available', () => { | ||
const mockOtrInstance = { | ||
getState: jest.fn().mockReturnValue(OtrRoomState.NOT_STARTED), | ||
}; | ||
(useUserId as jest.Mock).mockReturnValue('userId'); | ||
(useRoom as jest.Mock).mockReturnValue({ _id: 'roomId' }); | ||
(OTR.getInstanceByRoomId as jest.Mock).mockReturnValue(mockOtrInstance); | ||
|
||
const { result } = renderHook(() => useOTR()); | ||
|
||
expect(result.current.otr).toBe(mockOtrInstance); | ||
expect(result.current.otrState).toBe(OtrRoomState.NOT_STARTED); | ||
}); | ||
}); |
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,28 @@ | ||
import { useUserId } from '@rocket.chat/ui-contexts'; | ||
import { useMemo, useCallback } from 'react'; | ||
|
||
import OTR from '../../app/otr/client/OTR'; | ||
import type { OTRRoom } from '../../app/otr/client/OTRRoom'; | ||
import { OtrRoomState } from '../../app/otr/lib/OtrRoomState'; | ||
import { useRoom } from '../views/room/contexts/RoomContext'; | ||
import { useReactiveValue } from './useReactiveValue'; | ||
|
||
export const useOTR = (): { otr: OTRRoom | undefined; otrState: OtrRoomState } => { | ||
const uid = useUserId(); | ||
const room = useRoom(); | ||
|
||
const otr = useMemo(() => { | ||
if (!uid || !room) { | ||
return; | ||
} | ||
|
||
return OTR.getInstanceByRoomId(uid, room._id); | ||
}, [uid, room]); | ||
|
||
const otrState = useReactiveValue(useCallback(() => (otr ? otr.getState() : OtrRoomState.ERROR), [otr])); | ||
|
||
return { | ||
otr, | ||
otrState, | ||
}; | ||
}; |
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
17 changes: 3 additions & 14 deletions
17
apps/meteor/client/views/room/contextualBar/OTR/OTRWithData.tsx
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.