Skip to content

Commit

Permalink
fix: UserCard sanitization
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris committed Apr 7, 2022
1 parent 8f9b2d1 commit e4a540e
Show file tree
Hide file tree
Showing 17 changed files with 226 additions and 166 deletions.
11 changes: 0 additions & 11 deletions client/components/UserCard/Action.js

This file was deleted.

6 changes: 0 additions & 6 deletions client/components/UserCard/Info.js

This file was deleted.

10 changes: 0 additions & 10 deletions client/components/UserCard/Role.js

This file was deleted.

11 changes: 0 additions & 11 deletions client/components/UserCard/Roles.js

This file was deleted.

92 changes: 0 additions & 92 deletions client/components/UserCard/UserCard.js

This file was deleted.

15 changes: 13 additions & 2 deletions client/components/UserCard/UserCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,20 @@ export default {
args: {
name: 'guilherme.gazzo',
customStatus: '🛴 currently working on User Card',
roles: [<UserCard.Role>Admin</UserCard.Role>, <UserCard.Role>Rocket.Chat</UserCard.Role>, <UserCard.Role>Team</UserCard.Role>],
roles: (
<>
<UserCard.Role>Admin</UserCard.Role>
<UserCard.Role>Rocket.Chat</UserCard.Role>
<UserCard.Role>Team</UserCard.Role>
</>
),
bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus, eros convallis vulputate cursus, nisi neque eleifend libero, eget lacinia justo purus nec est. In at sodales ipsum. Sed lacinia quis purus eget pulvinar. Aenean eu pretium nunc, at aliquam magna. Praesent dignissim, tortor sed volutpat mattis, mauris diam pulvinar leo, porta commodo risus est non purus. Mauris in justo vel lorem ullamcorper hendrerit. Nam est metus, viverra a pellentesque vitae, ornare eget odio. Morbi tempor feugiat mattis. Morbi non felis tempor, aliquam justo sed, sagittis nibh. Mauris consequat ex metus. Praesent sodales sit amet nibh a vulputate. Integer commodo, mi vel bibendum sollicitudin, urna lectus accumsan ante, eget faucibus augue ex id neque. Aenean consectetur, orci a pellentesque mattis, tortor tellus fringilla elit, non ullamcorper risus nunc feugiat risus. Fusce sit amet nisi dapibus turpis commodo placerat. In tortor ante, vehicula sit amet augue et, imperdiet porta sem.',
actions: [<UserCard.Action icon='message' />, <UserCard.Action icon='phone' />],
actions: (
<>
<UserCard.Action icon='message' />
<UserCard.Action icon='phone' />
</>
),
localTime: 'Local Time: 7:44 AM',
},
} as ComponentMeta<typeof UserCard>;
Expand Down
118 changes: 118 additions & 0 deletions client/components/UserCard/UserCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { css } from '@rocket.chat/css-in-js';
import { Box, ActionButton, Skeleton } from '@rocket.chat/fuselage';
import React, { forwardRef, ReactNode, ComponentProps } from 'react';

import { useTranslation } from '../../contexts/TranslationContext';
import MarkdownText from '../MarkdownText';
import * as Status from '../UserStatus';
import UserAvatar from '../avatar/UserAvatar';
import UserCardContainer from './UserCardContainer';
import UserCardInfo from './UserCardInfo';
import UserCardRoles from './UserCardRoles';
import UserCardUsername from './UserCardUsername';

const clampStyle = css`
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
word-break: break-all;
`;

type UserCardProps = {
className?: string;
style?: ComponentProps<typeof Box>['style'];
open?: () => void;
name?: string;
username?: string;
etag?: string;
customStatus?: ReactNode;
roles?: ReactNode;
bio?: ReactNode;
status?: ReactNode;
actions?: ReactNode;
localTime?: ReactNode;
onClose?: () => void;
nickname?: string;
};

const UserCard = forwardRef(function UserCard(
{
className,
style,
open,
name,
username,
etag,
customStatus = <Skeleton width='100%' />,
roles = (
<>
<Skeleton width='32%' mi='x2' />
<Skeleton width='32%' mi='x2' />
<Skeleton width='32%' mi='x2' />
</>
),
bio = (
<>
<Skeleton width='100%' />
<Skeleton width='100%' />
<Skeleton width='100%' />
</>
),
status = <Status.Offline />,
actions,
localTime = <Skeleton width='100%' />,
onClose,
nickname,
}: UserCardProps,
ref,
) {
const t = useTranslation();

return (
<UserCardContainer className={className} ref={ref} style={style}>
<Box>
{!username ? <Skeleton width='x124' height='x124' variant='rect' /> : <UserAvatar username={username} etag={etag} size='x124' />}
{actions && (
<Box flexGrow={0} display='flex' mb='x12' alignItems='center' justifyContent='center'>
{actions}
</Box>
)}
</Box>
<Box display='flex' flexDirection='column' flexGrow={1} flexShrink={1} mis='x24' width='1px'>
<Box mbe='x4' withTruncatedText display='flex'>
{!name ? <Skeleton width='100%' /> : <UserCardUsername status={status} name={name} />}
{nickname && (
<Box flexGrow={1} flexShrink={1} flexBasis={0} title={t('Nickname')} color='hint' mis='x4' fontScale='p2' withTruncatedText>
({nickname})
</Box>
)}
</Box>
{customStatus && (
<UserCardInfo>
{typeof customStatus === 'string' ? (
<MarkdownText withTruncatedText variant='inlineWithoutBreaks' content={customStatus} parseEmoji={true} />
) : (
customStatus
)}
</UserCardInfo>
)}
<UserCardRoles>{roles}</UserCardRoles>
<UserCardInfo>{localTime}</UserCardInfo>
{bio && (
<UserCardInfo withTruncatedText={false} className={clampStyle} height='x60'>
{typeof bio === 'string' ? <MarkdownText variant='inline' content={bio} /> : bio}
</UserCardInfo>
)}
{open && <a onClick={open}>{t('See_full_profile')}</a>}
</Box>
{onClose && (
<Box>
<ActionButton small ghost title={t('Close')} icon='cross' onClick={onClose} />
</Box>
)}
</UserCardContainer>
);
});

export default UserCard;
13 changes: 13 additions & 0 deletions client/components/UserCard/UserCardAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ActionButton, Icon } from '@rocket.chat/fuselage';
import React, { ReactElement, ComponentProps } from 'react';

type UserCardActionProps = {
label?: string;
icon: ComponentProps<typeof Icon>['name'];
};

const UserCardAction = ({ label, icon, ...props }: UserCardActionProps): ReactElement => (
<ActionButton icon={icon} small title={label} {...props} mi='x2' />
);

export default UserCardAction;
8 changes: 0 additions & 8 deletions client/components/UserCard/UserCardContainer.js

This file was deleted.

8 changes: 8 additions & 0 deletions client/components/UserCard/UserCardContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Box } from '@rocket.chat/fuselage';
import React, { forwardRef, ComponentProps } from 'react';

const UserCardContainer = forwardRef(function UserCardContainer(props: ComponentProps<typeof Box>, ref) {
return <Box ref={ref} rcx-user-card bg='surface' elevation='2' p='x24' display='flex' borderRadius='x2' width='439px' {...props} />;
});

export default UserCardContainer;
8 changes: 8 additions & 0 deletions client/components/UserCard/UserCardInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Box } from '@rocket.chat/fuselage';
import React, { ReactElement, ComponentProps } from 'react';

const UserCardInfo = (props: ComponentProps<typeof Box>): ReactElement => (
<Box mbe='x8' is='span' fontScale='p2' color='hint' withTruncatedText {...props} />
);

export default UserCardInfo;
10 changes: 10 additions & 0 deletions client/components/UserCard/UserCardRole.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Box, Tag } from '@rocket.chat/fuselage';
import React, { ReactNode, ReactElement } from 'react';

const UserCardRole = ({ children }: { children: ReactNode }): ReactElement => (
<Box m='x2' fontScale='c2'>
<Tag disabled children={children} />
</Box>
);

export default UserCardRole;
14 changes: 14 additions & 0 deletions client/components/UserCard/UserCardRoles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Box } from '@rocket.chat/fuselage';
import React, { ReactNode, ReactElement } from 'react';

import UserCardInfo from './UserCardInfo';

const UserCardRoles = ({ children }: { children: ReactNode }): ReactElement => (
<Box m='neg-x2'>
<UserCardInfo flexWrap='wrap' display='flex' flexShrink={0}>
{children}
</UserCardInfo>
</Box>
);

export default UserCardRoles;
31 changes: 31 additions & 0 deletions client/components/UserCard/UserCardUsername.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Box } from '@rocket.chat/fuselage';
import React, { ReactElement, ReactNode, ComponentProps } from 'react';

import * as UserStatus from '../UserStatus';

type UserCardUsernameProps = ComponentProps<typeof Box> & {
name: ReactNode;
status: ReactNode;
};

const UserCardUsername = ({ name, status = <UserStatus.Offline />, ...props }: UserCardUsernameProps): ReactElement => (
<Box
display='flex'
title={name}
flexGrow={2}
flexShrink={1}
flexBasis={0}
alignItems='center'
fontScale='h4'
color='default'
withTruncatedText
{...props}
>
{status}{' '}
<Box mis='x8' flexGrow={1} withTruncatedText>
{name}
</Box>
</Box>
);

export default UserCardUsername;
15 changes: 0 additions & 15 deletions client/components/UserCard/Username.js

This file was deleted.

Loading

0 comments on commit e4a540e

Please sign in to comment.