Skip to content

Commit

Permalink
Merge branch 'develop' into e2e-disable-messageActions
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Jun 19, 2024
2 parents 35bb794 + cd97aac commit 165e52c
Show file tree
Hide file tree
Showing 27 changed files with 252 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/happy-cameras-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed an issue where private encrypted room creation was being forced even when E2EE feature was disabled.
5 changes: 5 additions & 0 deletions .changeset/hungry-waves-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixed file name being incorrectly sent from the client when uploading assets
5 changes: 5 additions & 0 deletions .changeset/odd-goats-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes an issue where settings code mirror is not being displayed correctly in full screen mode
6 changes: 6 additions & 0 deletions .changeset/popular-bulldogs-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/i18n': patch
'@rocket.chat/meteor': patch
---

Disable slash commands in encrypted rooms and show a disabled warning.
5 changes: 5 additions & 0 deletions .changeset/proud-coats-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fix the sorting by last chat in Contact Center table
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Palette } from '@rocket.chat/fuselage';
import type { ScrollValues } from 'rc-scrollbars';
import { Scrollbars } from 'rc-scrollbars';
import type { MutableRefObject, CSSProperties, ReactNode, ReactElement } from 'react';
import React, { memo, forwardRef, useCallback } from 'react';
import type { MutableRefObject, CSSProperties, ReactNode } from 'react';
import React, { memo, forwardRef, useCallback, useMemo } from 'react';

export type CustomScrollbarsProps = {
overflowX?: boolean;
Expand All @@ -14,10 +14,18 @@ export type CustomScrollbarsProps = {
autoHide?: boolean;
};

const styleDefault: CSSProperties = {
flexGrow: 1,
willChange: 'transform',
overflowY: 'hidden',
};

const CustomScrollbars = forwardRef<HTMLElement, CustomScrollbarsProps>(function CustomScrollbars(
{ children, onScroll, overflowX, renderView, ...props },
{ children, style, onScroll, overflowX, renderView, ...props },
ref,
) {
const scrollbarsStyle = useMemo(() => ({ ...style, ...styleDefault }), [style]);

const refSetter = useCallback(
(scrollbarRef) => {
if (ref && scrollbarRef) {
Expand All @@ -38,12 +46,11 @@ const CustomScrollbars = forwardRef<HTMLElement, CustomScrollbarsProps>(function
autoHide
autoHideTimeout={2000}
autoHideDuration={500}
style={scrollbarsStyle}
onScrollFrame={onScroll}
renderView={renderView}
renderTrackHorizontal={
overflowX ? undefined : (props): ReactElement => <div {...props} className='track-horizontal' style={{ display: 'none' }} />
}
renderThumbVertical={({ style, ...props }): JSX.Element => (
renderTrackHorizontal={overflowX ? undefined : (props) => <div {...props} className='track-horizontal' style={{ display: 'none' }} />}
renderThumbVertical={({ style, ...props }) => (
<div {...props} style={{ ...style, backgroundColor: Palette.stroke['stroke-dark'].toString(), borderRadius: '4px' }} />
)}
children={children}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ComponentProps, ReactElement, Ref } from 'react';
import type { ComponentProps, Ref } from 'react';
import React, { forwardRef } from 'react';

import CustomScrollbars from './CustomScrollbars';
Expand All @@ -8,13 +8,9 @@ type VirtuosoScrollbarsProps = ComponentProps<typeof CustomScrollbars>;
const VirtuosoScrollbars = forwardRef(function VirtuosoScrollbars(
{ style, children, ...props }: VirtuosoScrollbarsProps,
ref: Ref<HTMLDivElement>,
): ReactElement {
) {
return (
<CustomScrollbars
style={{ ...style, flexGrow: 1, overflowY: 'hidden', width: '100%', willChange: 'transform' }}
ref={ref}
renderView={(viewProps): ReactElement => <div {...viewProps} {...props} />}
>
<CustomScrollbars style={style} ref={ref} renderView={(viewProps) => <div {...viewProps} {...props} />}>
{children}
</CustomScrollbars>
);
Expand Down
10 changes: 9 additions & 1 deletion apps/meteor/client/lib/chats/ChatAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,15 @@ export type ChatAPI = {

readonly flows: {
readonly uploadFiles: (files: readonly File[], resetFileInput?: () => void) => Promise<void>;
readonly sendMessage: ({ text, tshow }: { text: string; tshow?: boolean; previewUrls?: string[] }) => Promise<boolean>;
readonly sendMessage: ({
text,
tshow,
}: {
text: string;
tshow?: boolean;
previewUrls?: string[];
isSlashCommandAllowed?: boolean;
}) => Promise<boolean>;
readonly processSlashCommand: (message: IMessage, userId: string | null) => Promise<boolean>;
readonly processTooLongMessage: (message: IMessage) => Promise<boolean>;
readonly processMessageEditing: (
Expand Down
13 changes: 9 additions & 4 deletions apps/meteor/client/lib/chats/flows/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { processSetReaction } from './processSetReaction';
import { processSlashCommand } from './processSlashCommand';
import { processTooLongMessage } from './processTooLongMessage';

const process = async (chat: ChatAPI, message: IMessage, previewUrls?: string[]): Promise<void> => {
const process = async (chat: ChatAPI, message: IMessage, previewUrls?: string[], isSlashCommandAllowed?: boolean): Promise<void> => {
KonchatNotification.removeRoomNotification(message.rid);

if (await processSetReaction(chat, message)) {
Expand All @@ -25,7 +25,7 @@ const process = async (chat: ChatAPI, message: IMessage, previewUrls?: string[])
return;
}

if (await processSlashCommand(chat, message)) {
if (isSlashCommandAllowed && (await processSlashCommand(chat, message))) {
return;
}

Expand All @@ -34,7 +34,12 @@ const process = async (chat: ChatAPI, message: IMessage, previewUrls?: string[])

export const sendMessage = async (
chat: ChatAPI,
{ text, tshow, previewUrls }: { text: string; tshow?: boolean; previewUrls?: string[] },
{
text,
tshow,
previewUrls,
isSlashCommandAllowed,
}: { text: string; tshow?: boolean; previewUrls?: string[]; isSlashCommandAllowed?: boolean },
): Promise<boolean> => {
if (!(await chat.data.isSubscribedToRoom())) {
try {
Expand Down Expand Up @@ -63,7 +68,7 @@ export const sendMessage = async (
});

try {
await process(chat, message, previewUrls);
await process(chat, message, previewUrls, isSlashCommandAllowed);
chat.composer?.dismissAllQuotedMessages();
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const CreateChannelModal = ({ teamId = '', onClose, reload }: CreateChannelModal
const namesValidation = useSetting('UTF8_Channel_Names_Validation');
const allowSpecialNames = useSetting('UI_Allow_room_names_with_special_chars');
const federationEnabled = useSetting<boolean>('Federation_Matrix_enabled') || false;
const e2eEnabledForPrivateByDefault = useSetting('E2E_Enabled_Default_PrivateRooms');
const e2eEnabledForPrivateByDefault = useSetting('E2E_Enabled_Default_PrivateRooms') && e2eEnabled;

const canCreateChannel = usePermission('create-c');
const canCreatePrivateChannel = usePermission('create-p');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function AssetSettingInput({ _id, label, value, asset, required, disabled, fileC
dispatchToastMessage({ type: 'info', message: t('Uploading_file') });

const fileData = new FormData();
fileData.append('asset', blob, asset);
fileData.append('asset', blob, blob.name);
fileData.append('assetName', asset);

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ const CodeMirrorBox = ({ label, children }: { label: ReactNode; children: ReactE
{label}
</Box>
)}
{children}
<Box display='flex' flexDirection='column' height='100%' role='code' aria-label={typeof label === 'string' ? label : undefined}>
{children}
</Box>
<Box mbs={8}>
<ButtonGroup>
<Button primary onClick={(): void => toggleFullScreen()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { useCurrentContacts } from './hooks/useCurrentContacts';

function ContactTable(): ReactElement {
const { current, itemsPerPage, setItemsPerPage, setCurrent, ...paginationProps } = usePagination();
const { sortBy, sortDirection, setSort } = useSort<'username' | 'phone' | 'name' | 'visitorEmails.address' | 'lastchat'>('username');
const { sortBy, sortDirection, setSort } = useSort<'username' | 'phone' | 'name' | 'visitorEmails.address' | 'lastChat.ts'>('username');
const isCallReady = useIsCallReady();

const [term, setTerm] = useDebouncedState('', 500);
Expand Down Expand Up @@ -90,7 +90,13 @@ function ContactTable(): ReactElement {
>
{t('Email')}
</GenericTableHeaderCell>
<GenericTableHeaderCell key='lastchat' direction={sortDirection} active={sortBy === 'lastchat'} onClick={setSort} sort='lastchat'>
<GenericTableHeaderCell
key='lastchat'
direction={sortDirection}
active={sortBy === 'lastChat.ts'}
onClick={setSort}
sort='lastChat.ts'
>
{t('Last_Chat')}
</GenericTableHeaderCell>
<GenericTableHeaderCell key='call' width={44} />
Expand Down
11 changes: 10 additions & 1 deletion apps/meteor/client/views/room/composer/ComposerBoxPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type ComposerBoxPopupProps<
T extends {
_id: string;
sort?: number;
disabled?: boolean;
},
> = {
title?: string;
Expand All @@ -22,6 +23,7 @@ function ComposerBoxPopup<
T extends {
_id: string;
sort?: number;
disabled?: boolean;
},
>({
title,
Expand All @@ -37,7 +39,9 @@ function ComposerBoxPopup<

const variant = popupSizes && popupSizes.inlineSize < 480 ? 'small' : 'large';

const getOptionTitle = <T extends { _id: string; sort?: number; outside?: boolean; suggestion?: boolean }>(item: T) => {
const getOptionTitle = <T extends { _id: string; sort?: number; outside?: boolean; suggestion?: boolean; disabled?: boolean }>(
item: T,
) => {
if (variant !== 'small') {
return undefined;
}
Expand All @@ -49,6 +53,10 @@ function ComposerBoxPopup<
if (item.suggestion) {
return t('Suggestion_from_recent_messages');
}

if (item.disabled) {
return t('Unavailable_in_encrypted_channels');
}
};

const itemsFlat = useMemo(
Expand Down Expand Up @@ -96,6 +104,7 @@ function ComposerBoxPopup<
id={`popup-item-${item._id}`}
tabIndex={item === focused ? 0 : -1}
aria-selected={item === focused}
disabled={item.disabled}
>
{renderItem({ item: { ...item, variant } })}
</Option>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { OptionColumn, OptionContent, OptionDescription, OptionInput } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';

export type ComposerBoxPopupSlashCommandProps = {
_id: string;
description?: string;
params?: string;
disabled?: boolean;
};

function ComposerBoxPopupSlashCommand({ _id, description, params }: ComposerBoxPopupSlashCommandProps) {
function ComposerBoxPopupSlashCommand({ _id, description, params, disabled }: ComposerBoxPopupSlashCommandProps) {
const t = useTranslation();

return (
<>
<OptionContent>
{_id} <OptionDescription>{params}</OptionDescription>
</OptionContent>
<OptionColumn>
<OptionInput>{description}</OptionInput>
<OptionInput>{disabled ? t('Unavailable_in_encrypted_channels') : description}</OptionInput>
</OptionColumn>
</>
);
Expand Down
13 changes: 12 additions & 1 deletion apps/meteor/client/views/room/composer/ComposerMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,24 @@ const ComposerMessage = ({ tmid, readOnly, onSend, ...props }: ComposerMessagePr
}
},

onSend: async ({ value: text, tshow, previewUrls }: { value: string; tshow?: boolean; previewUrls?: string[] }): Promise<void> => {
onSend: async ({
value: text,
tshow,
previewUrls,
isSlashCommandAllowed,
}: {
value: string;
tshow?: boolean;
previewUrls?: string[];
isSlashCommandAllowed?: boolean;
}): Promise<void> => {
try {
await chat?.action.stop('typing');
const newMessageSent = await chat?.flows.sendMessage({
text,
tshow,
previewUrls,
isSlashCommandAllowed,
});
if (newMessageSent) onSend?.();
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
MessageComposerHint,
MessageComposerButton,
} from '@rocket.chat/ui-composer';
import { useTranslation, useUserPreference, useLayout } from '@rocket.chat/ui-contexts';
import { useTranslation, useUserPreference, useLayout, useSetting } from '@rocket.chat/ui-contexts';
import { useMutation } from '@tanstack/react-query';
import type {
ReactElement,
Expand Down Expand Up @@ -92,7 +92,7 @@ const getEmptyArray = () => a;
type MessageBoxProps = {
tmid?: IMessage['_id'];
readOnly: boolean;
onSend?: (params: { value: string; tshow?: boolean; previewUrls?: string[] }) => Promise<void>;
onSend?: (params: { value: string; tshow?: boolean; previewUrls?: string[]; isSlashCommandAllowed?: boolean }) => Promise<void>;
onJoin?: () => Promise<void>;
onResize?: () => void;
onTyping?: () => void;
Expand Down Expand Up @@ -123,6 +123,9 @@ const MessageBox = ({
const chat = useChat();
const room = useRoom();
const t = useTranslation();
const e2eEnabled = useSetting<boolean>('E2E_Enable');
const unencryptedMessagesAllowed = useSetting<boolean>('E2E_Allow_Unencrypted_Messages');
const isSlashCommandAllowed = !e2eEnabled || !room.encrypted || unencryptedMessagesAllowed;
const composerPlaceholder = useMessageBoxPlaceholder(t('Message'), room);

const [typing, setTyping] = useReducer(reducer, false);
Expand Down Expand Up @@ -176,6 +179,7 @@ const MessageBox = ({
value: text,
tshow,
previewUrls,
isSlashCommandAllowed,
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type ComposerPopupOption<T extends { _id: string; sort?: number } = { _id
getValue: (item: T) => string;

renderItem?: ({ item }: { item: T }) => ReactElement;
disabled?: boolean;
};

export type ComposerPopupContextValue = ComposerPopupOption[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ import type { ComposerPopupContextValue } from '../contexts/ComposerPopupContext
import { ComposerPopupContext, createMessageBoxPopupConfig } from '../contexts/ComposerPopupContext';

const ComposerPopupProvider = ({ children, room }: { children: ReactNode; room: IRoom }) => {
const { _id: rid } = room;
const { _id: rid, encrypted: isRoomEncrypted } = room;
const userSpotlight = useMethod('spotlight');
const suggestionsCount = useSetting<number>('Number_of_users_autocomplete_suggestions');
const cannedResponseEnabled = useSetting<boolean>('Canned_Responses_Enable');
const [recentEmojis] = useLocalStorage('emoji.recent', []);
const isOmnichannel = isOmnichannelRoom(room);
const useEmoji = useUserPreference('useEmojis');
const t = useTranslation();
const e2eEnabled = useSetting<boolean>('E2E_Enable');
const unencryptedMessagesAllowed = useSetting<boolean>('E2E_Allow_Unencrypted_Messages');
const encrypted = isRoomEncrypted && e2eEnabled && !unencryptedMessagesAllowed;

const call = useMethod('getSlashCommandPreviews');
const value: ComposerPopupContextValue = useMemo(() => {
Expand Down Expand Up @@ -278,6 +281,7 @@ const ComposerPopupProvider = ({ children, room }: { children: ReactNode; room:
trigger: '/',
suffix: ' ',
triggerAnywhere: false,
disabled: encrypted,
renderItem: ({ item }) => <ComposerBoxPopupSlashCommand {...item} />,
getItemsFromLocal: async (filter: string) => {
return Object.keys(slashCommands.commands)
Expand All @@ -288,6 +292,7 @@ const ComposerPopupProvider = ({ children, room }: { children: ReactNode; room:
params: item.params && t.has(item.params) ? t(item.params) : item.params ?? '',
description: item.description && t.has(item.description) ? t(item.description) : item.description,
permission: item.permission,
...(encrypted && { disabled: encrypted }),
};
})
.filter((command) => {
Expand Down Expand Up @@ -360,7 +365,7 @@ const ComposerPopupProvider = ({ children, room }: { children: ReactNode; room:
},
}),
].filter(Boolean);
}, [t, cannedResponseEnabled, isOmnichannel, recentEmojis, suggestionsCount, userSpotlight, rid, call, useEmoji]);
}, [t, cannedResponseEnabled, isOmnichannel, recentEmojis, suggestionsCount, userSpotlight, rid, call, useEmoji, encrypted]);

return <ComposerPopupContext.Provider value={value} children={children} />;
};
Expand Down
Loading

0 comments on commit 165e52c

Please sign in to comment.