Reenable header, add disable e2ee on header if needed, disable most of actions on RoomActionsView
This commit is contained in:
parent
354e15619e
commit
0bea843ffa
|
@ -841,5 +841,11 @@
|
||||||
"Your_invite_link_will_never_expire": "Your invite link will never expire.",
|
"Your_invite_link_will_never_expire": "Your invite link will never expire.",
|
||||||
"Your_password_is": "Your password is",
|
"Your_password_is": "Your password is",
|
||||||
"Your_push_was_sent_to_s_devices": "Your push was sent to {{s}} devices",
|
"Your_push_was_sent_to_s_devices": "Your push was sent to {{s}} devices",
|
||||||
"Your_workspace": "Your workspace"
|
"Your_workspace": "Your workspace",
|
||||||
|
"Enable": "Enable",
|
||||||
|
"Disable": "Disable",
|
||||||
|
"Disable_encryption_title": "Disable encryption",
|
||||||
|
"Enable_encryption_title": "Enable encryption",
|
||||||
|
"Disable_encryption_description": "Disabling E2EE compromises privacy. You can re-enable it later if needed. Proceed with caution.",
|
||||||
|
"Enable_encryption_description": "Ensure conversations are kept private"
|
||||||
}
|
}
|
|
@ -827,5 +827,11 @@
|
||||||
"Your_invite_link_will_never_expire": "Seu link de convite nunca irá vencer.",
|
"Your_invite_link_will_never_expire": "Seu link de convite nunca irá vencer.",
|
||||||
"Your_password_is": "Sua senha é",
|
"Your_password_is": "Sua senha é",
|
||||||
"Your_push_was_sent_to_s_devices": "A sua notificação foi enviada para {{s}} dispositivos",
|
"Your_push_was_sent_to_s_devices": "A sua notificação foi enviada para {{s}} dispositivos",
|
||||||
"Your_workspace": "Sua workspace"
|
"Your_workspace": "Sua workspace",
|
||||||
|
"Enable": "Habilitar",
|
||||||
|
"Disable": "Desabilitar",
|
||||||
|
"Disable_encryption_title": "Desabilitar criptografia",
|
||||||
|
"Enable_encryption_title": "Habilitar criptografia",
|
||||||
|
"Disable_encryption_description": "Desabilitar a criptografia compromete sua privacidade. Você pode reabilitá-la depois se precisar. Continue com cautela.",
|
||||||
|
"Enable_encryption_description": "Garante a privacidade das suas conversas"
|
||||||
}
|
}
|
|
@ -501,26 +501,6 @@ class Encryption {
|
||||||
|
|
||||||
// Decrypt multiple subscriptions
|
// Decrypt multiple subscriptions
|
||||||
decryptSubscriptions = (subscriptions: ISubscription[]) => Promise.all(subscriptions.map(s => this.decryptSubscription(s)));
|
decryptSubscriptions = (subscriptions: ISubscription[]) => Promise.all(subscriptions.map(s => this.decryptSubscription(s)));
|
||||||
|
|
||||||
// Missing room encryption key
|
|
||||||
isMissingRoomE2EEKey = ({
|
|
||||||
encryptionEnabled,
|
|
||||||
roomEncrypted,
|
|
||||||
E2EKey
|
|
||||||
}: {
|
|
||||||
encryptionEnabled: boolean;
|
|
||||||
roomEncrypted: TSubscriptionModel['encrypted'];
|
|
||||||
E2EKey: TSubscriptionModel['E2EKey'];
|
|
||||||
}) => (encryptionEnabled && roomEncrypted && !E2EKey) ?? false;
|
|
||||||
|
|
||||||
// Encrypted room, but user session is not encrypted
|
|
||||||
isE2EEDisabledEncryptedRoom = ({
|
|
||||||
encryptionEnabled,
|
|
||||||
roomEncrypted
|
|
||||||
}: {
|
|
||||||
encryptionEnabled: boolean;
|
|
||||||
roomEncrypted: TSubscriptionModel['encrypted'];
|
|
||||||
}) => (!encryptionEnabled && roomEncrypted) ?? false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const encryption = new Encryption();
|
const encryption = new Encryption();
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
import { Alert } from 'react-native';
|
||||||
|
|
||||||
|
import { Services } from '../../services';
|
||||||
|
import database from '../../database';
|
||||||
|
import { getSubscriptionByRoomId } from '../../database/services/Subscription';
|
||||||
|
import log from '../../methods/helpers/log';
|
||||||
|
import I18n from '../../../i18n';
|
||||||
|
|
||||||
|
export const toggleRoomE2EE = async (rid: string): Promise<void> => {
|
||||||
|
const room = await getSubscriptionByRoomId(rid);
|
||||||
|
if (!room) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isEncrypted = room.encrypted;
|
||||||
|
const title = I18n.t(isEncrypted ? 'Disable_encryption_title' : 'Enable_encryption_title');
|
||||||
|
const message = I18n.t(isEncrypted ? 'Disable_encryption_description' : 'Enable_encryption_description');
|
||||||
|
const confirmationText = I18n.t(isEncrypted ? 'Disable' : 'Enable');
|
||||||
|
|
||||||
|
Alert.alert(
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: I18n.t('Cancel'),
|
||||||
|
style: 'cancel'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: confirmationText,
|
||||||
|
style: isEncrypted ? 'destructive' : 'default',
|
||||||
|
onPress: async () => {
|
||||||
|
try {
|
||||||
|
const db = database.active;
|
||||||
|
|
||||||
|
// Toggle encrypted value
|
||||||
|
const encrypted = !room.encrypted;
|
||||||
|
|
||||||
|
// Instantly feedback to the user
|
||||||
|
await db.write(async () => {
|
||||||
|
await room.update(r => {
|
||||||
|
r.encrypted = encrypted;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send new room setting value to server
|
||||||
|
const { result } = await Services.saveRoomSettings(rid, { encrypted });
|
||||||
|
// If it was saved successfully
|
||||||
|
if (result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// If something goes wrong we go back to the previous value
|
||||||
|
await db.write(async () => {
|
||||||
|
await room.update(r => {
|
||||||
|
r.encrypted = room.encrypted;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{ cancelable: true }
|
||||||
|
);
|
||||||
|
};
|
|
@ -3,6 +3,7 @@ import SimpleCrypto from 'react-native-simple-crypto';
|
||||||
|
|
||||||
import { random } from '../methods/helpers';
|
import { random } from '../methods/helpers';
|
||||||
import { fromByteArray, toByteArray } from './helpers/base64-js';
|
import { fromByteArray, toByteArray } from './helpers/base64-js';
|
||||||
|
import { TSubscriptionModel } from '../../definitions';
|
||||||
|
|
||||||
const BASE64URI = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
const BASE64URI = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
||||||
|
|
||||||
|
@ -58,3 +59,41 @@ export const toString = (thing: string | ByteBuffer | Buffer | ArrayBuffer | Uin
|
||||||
return new ByteBuffer.wrap(thing).toString('binary');
|
return new ByteBuffer.wrap(thing).toString('binary');
|
||||||
};
|
};
|
||||||
export const randomPassword = (): string => `${random(3)}-${random(3)}-${random(3)}`.toLowerCase();
|
export const randomPassword = (): string => `${random(3)}-${random(3)}-${random(3)}`.toLowerCase();
|
||||||
|
|
||||||
|
// Missing room encryption key
|
||||||
|
export const isMissingRoomE2EEKey = ({
|
||||||
|
encryptionEnabled,
|
||||||
|
roomEncrypted,
|
||||||
|
E2EKey
|
||||||
|
}: {
|
||||||
|
encryptionEnabled: boolean;
|
||||||
|
roomEncrypted: TSubscriptionModel['encrypted'];
|
||||||
|
E2EKey: TSubscriptionModel['E2EKey'];
|
||||||
|
}): boolean => (encryptionEnabled && roomEncrypted && !E2EKey) ?? false;
|
||||||
|
|
||||||
|
// Encrypted room, but user session is not encrypted
|
||||||
|
export const isE2EEDisabledEncryptedRoom = ({
|
||||||
|
encryptionEnabled,
|
||||||
|
roomEncrypted
|
||||||
|
}: {
|
||||||
|
encryptionEnabled: boolean;
|
||||||
|
roomEncrypted: TSubscriptionModel['encrypted'];
|
||||||
|
}): boolean => (!encryptionEnabled && roomEncrypted) ?? false;
|
||||||
|
|
||||||
|
export const hasE2EEWarning = ({
|
||||||
|
encryptionEnabled,
|
||||||
|
roomEncrypted,
|
||||||
|
E2EKey
|
||||||
|
}: {
|
||||||
|
encryptionEnabled: boolean;
|
||||||
|
roomEncrypted: TSubscriptionModel['encrypted'];
|
||||||
|
E2EKey: TSubscriptionModel['E2EKey'];
|
||||||
|
}): boolean => {
|
||||||
|
if (isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted, E2EKey })) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted })) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { store as reduxStore } from '../store/auxStore';
|
||||||
import { spotlight } from '../services/restApi';
|
import { spotlight } from '../services/restApi';
|
||||||
import { ISearch, ISearchLocal, IUserMessage, SubscriptionType, TSubscriptionModel } from '../../definitions';
|
import { ISearch, ISearchLocal, IUserMessage, SubscriptionType, TSubscriptionModel } from '../../definitions';
|
||||||
import { isGroupChat, isReadOnly } from './helpers';
|
import { isGroupChat, isReadOnly } from './helpers';
|
||||||
import { Encryption } from '../encryption';
|
import { isE2EEDisabledEncryptedRoom, isMissingRoomE2EEKey } from '../encryption/utils';
|
||||||
|
|
||||||
export type TSearch = ISearchLocal | IUserMessage | ISearch;
|
export type TSearch = ISearchLocal | IUserMessage | ISearch;
|
||||||
|
|
||||||
|
@ -54,10 +54,10 @@ export const localSearchSubscription = async ({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Encryption.isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted: item.encrypted, E2EKey: item.E2EKey })) {
|
if (isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted: item.encrypted, E2EKey: item.E2EKey })) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (Encryption.isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted: item.encrypted })) {
|
if (isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted: item.encrypted })) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
||||||
import * as List from '../../../containers/List';
|
import * as List from '../../../containers/List';
|
||||||
import { useVideoConf } from '../../../lib/hooks/useVideoConf';
|
import { useVideoConf } from '../../../lib/hooks/useVideoConf';
|
||||||
|
|
||||||
export default function CallSection({ rid }: { rid: string }): React.ReactElement | null {
|
export default function CallSection({ rid, disabled }: { rid: string; disabled: boolean }): React.ReactElement | null {
|
||||||
const { callEnabled, showInitCallActionSheet, disabledTooltip } = useVideoConf(rid);
|
const { callEnabled, showInitCallActionSheet, disabledTooltip } = useVideoConf(rid);
|
||||||
if (callEnabled)
|
if (callEnabled)
|
||||||
return (
|
return (
|
||||||
|
@ -15,7 +15,7 @@ export default function CallSection({ rid }: { rid: string }): React.ReactElemen
|
||||||
testID='room-actions-call'
|
testID='room-actions-call'
|
||||||
left={() => <List.Icon name='phone' />}
|
left={() => <List.Icon name='phone' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
disabled={disabledTooltip}
|
disabled={disabledTooltip || disabled}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</List.Section>
|
</List.Section>
|
||||||
|
|
|
@ -54,6 +54,8 @@ import { ILivechatTag } from '../../definitions/ILivechatTag';
|
||||||
import CallSection from './components/CallSection';
|
import CallSection from './components/CallSection';
|
||||||
import { TNavigation } from '../../stacks/stackType';
|
import { TNavigation } from '../../stacks/stackType';
|
||||||
import Switch from '../../containers/Switch';
|
import Switch from '../../containers/Switch';
|
||||||
|
import * as EncryptionUtils from '../../lib/encryption/utils';
|
||||||
|
import { toggleRoomE2EE } from '../../lib/encryption/helpers/toggleRoomE2EE';
|
||||||
|
|
||||||
type StackType = ChatsStackParamList & TNavigation;
|
type StackType = ChatsStackParamList & TNavigation;
|
||||||
|
|
||||||
|
@ -100,6 +102,7 @@ interface IRoomActionsViewState {
|
||||||
canCreateTeam: boolean;
|
canCreateTeam: boolean;
|
||||||
canAddChannelToTeam: boolean;
|
canAddChannelToTeam: boolean;
|
||||||
canConvertTeam: boolean;
|
canConvertTeam: boolean;
|
||||||
|
hasE2EEWarning: boolean;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,13 +154,20 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
canCreateTeam: false,
|
canCreateTeam: false,
|
||||||
canAddChannelToTeam: false,
|
canAddChannelToTeam: false,
|
||||||
canConvertTeam: false,
|
canConvertTeam: false,
|
||||||
|
hasE2EEWarning: false,
|
||||||
loading: false
|
loading: false
|
||||||
};
|
};
|
||||||
if (room && room.observe && room.rid) {
|
if (room && room.observe && room.rid) {
|
||||||
|
const { encryptionEnabled } = this.props;
|
||||||
this.roomObservable = room.observe();
|
this.roomObservable = room.observe();
|
||||||
this.subscription = this.roomObservable.subscribe(changes => {
|
this.subscription = this.roomObservable.subscribe(changes => {
|
||||||
if (this.mounted) {
|
if (this.mounted) {
|
||||||
this.setState({ room: changes, membersCount: changes.usersCount });
|
const hasE2EEWarning = EncryptionUtils.hasE2EEWarning({
|
||||||
|
encryptionEnabled,
|
||||||
|
E2EKey: room.E2EKey,
|
||||||
|
roomEncrypted: room.encrypted
|
||||||
|
});
|
||||||
|
this.setState({ room: changes, membersCount: changes.usersCount, hasE2EEWarning });
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.state.room = changes;
|
this.state.room = changes;
|
||||||
|
@ -171,6 +181,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
this.mounted = true;
|
this.mounted = true;
|
||||||
const { room, member } = this.state;
|
const { room, member } = this.state;
|
||||||
|
const { encryptionEnabled } = this.props;
|
||||||
if (room.rid) {
|
if (room.rid) {
|
||||||
if (!room.id) {
|
if (!room.id) {
|
||||||
if (room.t === SubscriptionType.OMNICHANNEL) {
|
if (room.t === SubscriptionType.OMNICHANNEL) {
|
||||||
|
@ -214,6 +225,11 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
const canCreateTeam = await this.canCreateTeam();
|
const canCreateTeam = await this.canCreateTeam();
|
||||||
const canAddChannelToTeam = await this.canAddChannelToTeam();
|
const canAddChannelToTeam = await this.canAddChannelToTeam();
|
||||||
const canConvertTeam = await this.canConvertTeam();
|
const canConvertTeam = await this.canConvertTeam();
|
||||||
|
const hasE2EEWarning = EncryptionUtils.hasE2EEWarning({
|
||||||
|
encryptionEnabled,
|
||||||
|
E2EKey: room.E2EKey,
|
||||||
|
roomEncrypted: room.encrypted
|
||||||
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
canAutoTranslate,
|
canAutoTranslate,
|
||||||
|
@ -222,7 +238,8 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
canViewMembers,
|
canViewMembers,
|
||||||
canCreateTeam,
|
canCreateTeam,
|
||||||
canAddChannelToTeam,
|
canAddChannelToTeam,
|
||||||
canConvertTeam
|
canConvertTeam,
|
||||||
|
hasE2EEWarning
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,7 +362,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
|
|
||||||
renderEncryptedSwitch = () => {
|
renderEncryptedSwitch = () => {
|
||||||
const { room, canToggleEncryption, canEdit } = this.state;
|
const { room, canToggleEncryption, canEdit } = this.state;
|
||||||
const { encrypted } = room;
|
const { rid, encrypted } = room;
|
||||||
const { serverVersion } = this.props;
|
const { serverVersion } = this.props;
|
||||||
let hasPermission = false;
|
let hasPermission = false;
|
||||||
if (compareServerVersion(serverVersion, 'lowerThan', '3.11.0')) {
|
if (compareServerVersion(serverVersion, 'lowerThan', '3.11.0')) {
|
||||||
|
@ -353,7 +370,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
} else {
|
} else {
|
||||||
hasPermission = canToggleEncryption;
|
hasPermission = canToggleEncryption;
|
||||||
}
|
}
|
||||||
return <Switch value={encrypted} onValueChange={this.toggleEncrypted} disabled={!hasPermission} />;
|
return <Switch value={encrypted} onValueChange={() => toggleRoomE2EE(rid)} disabled={!hasPermission} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
closeLivechat = async () => {
|
closeLivechat = async () => {
|
||||||
|
@ -477,49 +494,6 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleEncrypted = async () => {
|
|
||||||
logEvent(events.RA_TOGGLE_ENCRYPTED);
|
|
||||||
const { room } = this.state;
|
|
||||||
const { rid } = room;
|
|
||||||
const db = database.active;
|
|
||||||
|
|
||||||
// Toggle encrypted value
|
|
||||||
const encrypted = !room.encrypted;
|
|
||||||
try {
|
|
||||||
// Instantly feedback to the user
|
|
||||||
await db.write(async () => {
|
|
||||||
await room.update(
|
|
||||||
protectedFunction((r: TSubscriptionModel) => {
|
|
||||||
r.encrypted = encrypted;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Send new room setting value to server
|
|
||||||
const { result } = await Services.saveRoomSettings(rid, { encrypted });
|
|
||||||
// If it was saved successfully
|
|
||||||
if (result) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
// If something goes wrong we go back to the previous value
|
|
||||||
await db.write(async () => {
|
|
||||||
await room.update(
|
|
||||||
protectedFunction((r: TSubscriptionModel) => {
|
|
||||||
r.encrypted = room.encrypted;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
logEvent(events.RA_TOGGLE_ENCRYPTED_F);
|
|
||||||
log(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
handleShare = () => {
|
handleShare = () => {
|
||||||
logEvent(events.RA_SHARE);
|
logEvent(events.RA_SHARE);
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
|
@ -938,7 +912,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
};
|
};
|
||||||
|
|
||||||
teamChannelActions = (t: string, room: ISubscription) => {
|
teamChannelActions = (t: string, room: ISubscription) => {
|
||||||
const { canEdit, canCreateTeam, canAddChannelToTeam } = this.state;
|
const { canEdit, canCreateTeam, canAddChannelToTeam, hasE2EEWarning } = this.state;
|
||||||
const canConvertToTeam = canEdit && canCreateTeam && !room.teamMain;
|
const canConvertToTeam = canEdit && canCreateTeam && !room.teamMain;
|
||||||
const canMoveToTeam = canEdit && canAddChannelToTeam && !room.teamId;
|
const canMoveToTeam = canEdit && canAddChannelToTeam && !room.teamId;
|
||||||
|
|
||||||
|
@ -956,6 +930,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-convert-to-team'
|
testID='room-actions-convert-to-team'
|
||||||
left={() => <List.Icon name='teams' />}
|
left={() => <List.Icon name='teams' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -973,6 +948,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-move-to-team'
|
testID='room-actions-move-to-team'
|
||||||
left={() => <List.Icon name='channel-move-to-team' />}
|
left={() => <List.Icon name='channel-move-to-team' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -982,7 +958,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
};
|
};
|
||||||
|
|
||||||
teamToChannelActions = (t: string, room: ISubscription) => {
|
teamToChannelActions = (t: string, room: ISubscription) => {
|
||||||
const { canEdit, canConvertTeam, loading } = this.state;
|
const { canEdit, canConvertTeam, loading, hasE2EEWarning } = this.state;
|
||||||
const canConvertTeamToChannel = canEdit && canConvertTeam && !!room?.teamMain;
|
const canConvertTeamToChannel = canEdit && canConvertTeam && !!room?.teamMain;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -991,7 +967,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
<>
|
<>
|
||||||
<List.Item
|
<List.Item
|
||||||
title='Convert_to_Channel'
|
title='Convert_to_Channel'
|
||||||
disabled={loading}
|
disabled={loading || hasE2EEWarning}
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
this.onPressTouchable({
|
this.onPressTouchable({
|
||||||
event: this.convertTeamToChannel
|
event: this.convertTeamToChannel
|
||||||
|
@ -1086,7 +1062,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { room, membersCount, canViewMembers, joined, canAutoTranslate } = this.state;
|
const { room, membersCount, canViewMembers, joined, canAutoTranslate, hasE2EEWarning } = this.state;
|
||||||
const { isMasterDetail, navigation } = this.props;
|
const { isMasterDetail, navigation } = this.props;
|
||||||
const { rid, t, prid, teamId } = room;
|
const { rid, t, prid, teamId } = room;
|
||||||
const isGroupChatHandler = isGroupChat(room);
|
const isGroupChatHandler = isGroupChat(room);
|
||||||
|
@ -1096,7 +1072,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
<StatusBar />
|
<StatusBar />
|
||||||
<List.Container testID='room-actions-scrollview'>
|
<List.Container testID='room-actions-scrollview'>
|
||||||
{this.renderRoomInfo()}
|
{this.renderRoomInfo()}
|
||||||
<CallSection rid={rid} />
|
<CallSection rid={rid} disabled={hasE2EEWarning} />
|
||||||
{this.renderE2EEncryption()}
|
{this.renderE2EEncryption()}
|
||||||
<List.Section>
|
<List.Section>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
|
@ -1132,6 +1108,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-discussions'
|
testID='room-actions-discussions'
|
||||||
left={() => <List.Icon name='discussions' />}
|
left={() => <List.Icon name='discussions' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1158,6 +1135,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-teams'
|
testID='room-actions-teams'
|
||||||
left={() => <List.Icon name='channel-public' />}
|
left={() => <List.Icon name='channel-public' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1187,6 +1165,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-files'
|
testID='room-actions-files'
|
||||||
left={() => <List.Icon name='attach' />}
|
left={() => <List.Icon name='attach' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1205,6 +1184,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-mentioned'
|
testID='room-actions-mentioned'
|
||||||
left={() => <List.Icon name='mention' />}
|
left={() => <List.Icon name='mention' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1223,6 +1203,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-starred'
|
testID='room-actions-starred'
|
||||||
left={() => <List.Icon name='star' />}
|
left={() => <List.Icon name='star' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1240,6 +1221,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-share'
|
testID='room-actions-share'
|
||||||
left={() => <List.Icon name='share' />}
|
left={() => <List.Icon name='share' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1258,6 +1240,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-pinned'
|
testID='room-actions-pinned'
|
||||||
left={() => <List.Icon name='pin' />}
|
left={() => <List.Icon name='pin' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1276,6 +1259,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-auto-translate'
|
testID='room-actions-auto-translate'
|
||||||
left={() => <List.Icon name='language' />}
|
left={() => <List.Icon name='language' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
@ -1294,6 +1278,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
testID='room-actions-notifications'
|
testID='room-actions-notifications'
|
||||||
left={() => <List.Icon name='notification' />}
|
left={() => <List.Icon name='notification' />}
|
||||||
showActionIndicator
|
showActionIndicator
|
||||||
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { TNavigation } from '../../stacks/stackType';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
import { ChatsStackParamList } from '../../stacks/types';
|
||||||
import { HeaderCallButton } from './components';
|
import { HeaderCallButton } from './components';
|
||||||
import { TColors, TSupportedThemes, withTheme } from '../../theme';
|
import { TColors, TSupportedThemes, withTheme } from '../../theme';
|
||||||
|
import { toggleRoomE2EE } from '../../lib/encryption/helpers/toggleRoomE2EE';
|
||||||
|
|
||||||
interface IRightButtonsProps extends Pick<ISubscription, 't'> {
|
interface IRightButtonsProps extends Pick<ISubscription, 't'> {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
@ -48,7 +49,7 @@ interface IRightButtonsProps extends Pick<ISubscription, 't'> {
|
||||||
colors?: TColors;
|
colors?: TColors;
|
||||||
issuesWithNotifications: boolean;
|
issuesWithNotifications: boolean;
|
||||||
notificationsDisabled?: boolean;
|
notificationsDisabled?: boolean;
|
||||||
disabled: boolean;
|
hasE2EEWarning: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRigthButtonsState {
|
interface IRigthButtonsState {
|
||||||
|
@ -97,8 +98,16 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) {
|
shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) {
|
||||||
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
||||||
const { teamId, status, joined, omnichannelPermissions, theme, disabled, issuesWithNotifications, notificationsDisabled } =
|
const {
|
||||||
this.props;
|
teamId,
|
||||||
|
status,
|
||||||
|
joined,
|
||||||
|
omnichannelPermissions,
|
||||||
|
theme,
|
||||||
|
hasE2EEWarning,
|
||||||
|
issuesWithNotifications,
|
||||||
|
notificationsDisabled
|
||||||
|
} = this.props;
|
||||||
if (nextProps.teamId !== teamId) {
|
if (nextProps.teamId !== teamId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -111,9 +120,6 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
if (nextProps.theme !== theme) {
|
if (nextProps.theme !== theme) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (nextProps.disabled !== disabled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (nextState.isFollowingThread !== isFollowingThread) {
|
if (nextState.isFollowingThread !== isFollowingThread) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +129,9 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
if (nextProps.notificationsDisabled !== notificationsDisabled) {
|
if (nextProps.notificationsDisabled !== notificationsDisabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (nextProps.hasE2EEWarning !== hasE2EEWarning) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!dequal(nextProps.omnichannelPermissions, omnichannelPermissions)) {
|
if (!dequal(nextProps.omnichannelPermissions, omnichannelPermissions)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -366,18 +375,17 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
||||||
const { t, tmid, threadsEnabled, rid, colors, issuesWithNotifications, notificationsDisabled, disabled } = this.props;
|
const { t, tmid, threadsEnabled, rid, colors, issuesWithNotifications, notificationsDisabled, hasE2EEWarning } = this.props;
|
||||||
|
|
||||||
|
if (!rid) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (t === 'l') {
|
if (t === 'l') {
|
||||||
if (!this.isOmnichannelPreview()) {
|
if (!this.isOmnichannelPreview()) {
|
||||||
return (
|
return (
|
||||||
<HeaderButton.Container>
|
<HeaderButton.Container>
|
||||||
<HeaderButton.Item
|
<HeaderButton.Item iconName='kebab' onPress={this.showMoreActions} testID='room-view-header-omnichannel-kebab' />
|
||||||
iconName='kebab'
|
|
||||||
onPress={this.showMoreActions}
|
|
||||||
testID='room-view-header-omnichannel-kebab'
|
|
||||||
disabled={disabled}
|
|
||||||
/>
|
|
||||||
</HeaderButton.Container>
|
</HeaderButton.Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -390,33 +398,33 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
iconName={isFollowingThread ? 'notification' : 'notification-disabled'}
|
iconName={isFollowingThread ? 'notification' : 'notification-disabled'}
|
||||||
onPress={this.toggleFollowThread}
|
onPress={this.toggleFollowThread}
|
||||||
testID={isFollowingThread ? 'room-view-header-unfollow' : 'room-view-header-follow'}
|
testID={isFollowingThread ? 'room-view-header-unfollow' : 'room-view-header-follow'}
|
||||||
disabled={disabled}
|
|
||||||
/>
|
/>
|
||||||
</HeaderButton.Container>
|
</HeaderButton.Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<HeaderButton.Container>
|
<HeaderButton.Container>
|
||||||
|
{hasE2EEWarning ? <HeaderButton.Item iconName='encrypted' onPress={() => toggleRoomE2EE(rid)} /> : null}
|
||||||
{issuesWithNotifications || notificationsDisabled ? (
|
{issuesWithNotifications || notificationsDisabled ? (
|
||||||
<HeaderButton.Item
|
<HeaderButton.Item
|
||||||
color={issuesWithNotifications ? colors!.fontDanger : ''}
|
color={issuesWithNotifications ? colors!.fontDanger : ''}
|
||||||
iconName='notification-disabled'
|
iconName='notification-disabled'
|
||||||
onPress={this.navigateToNotificationOrPushTroubleshoot}
|
onPress={this.navigateToNotificationOrPushTroubleshoot}
|
||||||
testID='room-view-push-troubleshoot'
|
testID='room-view-push-troubleshoot'
|
||||||
disabled={disabled}
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{rid ? <HeaderCallButton rid={rid} disabled={disabled} /> : null}
|
{rid ? <HeaderCallButton rid={rid} disabled={hasE2EEWarning} /> : null}
|
||||||
{threadsEnabled ? (
|
{threadsEnabled ? (
|
||||||
<HeaderButton.Item
|
<HeaderButton.Item
|
||||||
iconName='threads'
|
iconName='threads'
|
||||||
onPress={this.goThreadsView}
|
onPress={this.goThreadsView}
|
||||||
testID='room-view-header-threads'
|
testID='room-view-header-threads'
|
||||||
badge={() => <HeaderButton.BadgeUnread tunread={tunread} tunreadUser={tunreadUser} tunreadGroup={tunreadGroup} />}
|
badge={() => <HeaderButton.BadgeUnread tunread={tunread} tunreadUser={tunreadUser} tunreadGroup={tunreadGroup} />}
|
||||||
disabled={disabled}
|
disabled={hasE2EEWarning}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<HeaderButton.Item iconName='search' onPress={this.goSearchView} testID='room-view-search' disabled={disabled} />
|
<HeaderButton.Item iconName='search' onPress={this.goSearchView} testID='room-view-search' disabled={hasE2EEWarning} />
|
||||||
</HeaderButton.Container>
|
</HeaderButton.Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ import AudioManager from '../../lib/methods/AudioManager';
|
||||||
import { IListContainerRef, TListRef } from './List/definitions';
|
import { IListContainerRef, TListRef } from './List/definitions';
|
||||||
import { getMessageById } from '../../lib/database/services/Message';
|
import { getMessageById } from '../../lib/database/services/Message';
|
||||||
import { getThreadById } from '../../lib/database/services/Thread';
|
import { getThreadById } from '../../lib/database/services/Thread';
|
||||||
import { Encryption } from '../../lib/encryption';
|
import { hasE2EEWarning, isE2EEDisabledEncryptedRoom, isMissingRoomE2EEKey } from '../../lib/encryption/utils';
|
||||||
import { clearInAppFeedback, removeInAppFeedback } from '../../actions/inAppFeedback';
|
import { clearInAppFeedback, removeInAppFeedback } from '../../actions/inAppFeedback';
|
||||||
import UserPreferences from '../../lib/methods/userPreferences';
|
import UserPreferences from '../../lib/methods/userPreferences';
|
||||||
import { IRoomViewProps, IRoomViewState } from './definitions';
|
import { IRoomViewProps, IRoomViewState } from './definitions';
|
||||||
|
@ -415,23 +415,9 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
return hideSystemMessages ?? [];
|
return hideSystemMessages ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
hasE2EEWarning = () => {
|
|
||||||
const { room } = this.state;
|
|
||||||
const { encryptionEnabled } = this.props;
|
|
||||||
if ('encrypted' in room) {
|
|
||||||
if (Encryption.isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted: room.encrypted, E2EKey: room.E2EKey })) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Encryption.isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted: room.encrypted })) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
setHeader = () => {
|
setHeader = () => {
|
||||||
const { room, unreadsCount, roomUserId, joined, canForwardGuest, canReturnQueue, canPlaceLivechatOnHold } = this.state;
|
const { room, unreadsCount, roomUserId, joined, canForwardGuest, canReturnQueue, canPlaceLivechatOnHold } = this.state;
|
||||||
const { navigation, isMasterDetail, theme, baseUrl, user, route } = this.props;
|
const { navigation, isMasterDetail, theme, baseUrl, user, route, encryptionEnabled } = this.props;
|
||||||
const { rid, tmid } = this;
|
const { rid, tmid } = this;
|
||||||
if (!room.rid) {
|
if (!room.rid) {
|
||||||
return;
|
return;
|
||||||
|
@ -516,7 +502,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
onPress={this.goRoomActionsView}
|
onPress={this.goRoomActionsView}
|
||||||
testID={`room-view-title-${title}`}
|
testID={`room-view-title-${title}`}
|
||||||
sourceType={sourceType}
|
sourceType={sourceType}
|
||||||
disabled={this.hasE2EEWarning() || !!tmid}
|
disabled={!!tmid}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
|
@ -534,7 +520,9 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
showActionSheet={this.showActionSheet}
|
showActionSheet={this.showActionSheet}
|
||||||
departmentId={departmentId}
|
departmentId={departmentId}
|
||||||
notificationsDisabled={iSubRoom?.disableNotifications}
|
notificationsDisabled={iSubRoom?.disableNotifications}
|
||||||
disabled={this.hasE2EEWarning()}
|
hasE2EEWarning={
|
||||||
|
'encrypted' in room && hasE2EEWarning({ encryptionEnabled, E2EKey: room.E2EKey, roomEncrypted: room.encrypted })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1475,12 +1463,12 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
|
|
||||||
if ('encrypted' in room) {
|
if ('encrypted' in room) {
|
||||||
// Missing room encryption key
|
// Missing room encryption key
|
||||||
if (Encryption.isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted: room.encrypted, E2EKey: room.E2EKey })) {
|
if (isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted: room.encrypted, E2EKey: room.E2EKey })) {
|
||||||
return <MissingRoomE2EEKey />;
|
return <MissingRoomE2EEKey />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypted room, but user session is not encrypted
|
// Encrypted room, but user session is not encrypted
|
||||||
if (Encryption.isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted: room.encrypted })) {
|
if (isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted: room.encrypted })) {
|
||||||
return <EncryptedRoom navigation={navigation} roomName={getRoomTitle(room)} />;
|
return <EncryptedRoom navigation={navigation} roomName={getRoomTitle(room)} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,13 @@ import { animateNextTransition } from '../../lib/methods/helpers/layoutAnimation
|
||||||
import { TSupportedThemes, withTheme } from '../../theme';
|
import { TSupportedThemes, withTheme } from '../../theme';
|
||||||
import SafeAreaView from '../../containers/SafeAreaView';
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import { sanitizeLikeString } from '../../lib/database/utils';
|
import { sanitizeLikeString } from '../../lib/database/utils';
|
||||||
import { Encryption } from '../../lib/encryption';
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import ShareListHeader from './Header';
|
import ShareListHeader from './Header';
|
||||||
import { IApplicationState, TServerModel, TSubscriptionModel } from '../../definitions';
|
import { IApplicationState, TServerModel, TSubscriptionModel } from '../../definitions';
|
||||||
import { ShareInsideStackParamList } from '../../definitions/navigationTypes';
|
import { ShareInsideStackParamList } from '../../definitions/navigationTypes';
|
||||||
import { getRoomAvatar, isAndroid, isIOS, askAndroidMediaPermissions } from '../../lib/methods/helpers';
|
import { getRoomAvatar, isAndroid, isIOS, askAndroidMediaPermissions } from '../../lib/methods/helpers';
|
||||||
import { encryptionInit } from '../../actions/encryption';
|
import { encryptionInit } from '../../actions/encryption';
|
||||||
|
import { isE2EEDisabledEncryptedRoom, isMissingRoomE2EEKey } from '../../lib/encryption/utils';
|
||||||
|
|
||||||
interface IDataFromShare {
|
interface IDataFromShare {
|
||||||
value: string;
|
value: string;
|
||||||
|
@ -246,10 +246,10 @@ class ShareListView extends React.Component<IShareListViewProps, IState> {
|
||||||
|
|
||||||
return data
|
return data
|
||||||
.map(item => {
|
.map(item => {
|
||||||
if (Encryption.isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted: item.encrypted, E2EKey: item.E2EKey })) {
|
if (isMissingRoomE2EEKey({ encryptionEnabled, roomEncrypted: item.encrypted, E2EKey: item.E2EKey })) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (Encryption.isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted: item.encrypted })) {
|
if (isE2EEDisabledEncryptedRoom({ encryptionEnabled, roomEncrypted: item.encrypted })) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue