fix(client): 🐛 do not allow private resumes to be viewable or downloadable through the link

This commit is contained in:
Amruth Pillai
2023-07-12 15:59:22 +02:00
parent 5ef4bfcb6b
commit 1c2d796c50
121 changed files with 3193 additions and 2068 deletions

View File

@ -15,7 +15,7 @@
.controller {
@apply z-20 flex items-center justify-center shadow-lg;
@apply flex rounded-l-full rounded-r-full px-4;
@apply bg-neutral-50 dark:bg-neutral-800;
@apply bg-zinc-50 dark:bg-zinc-900;
@apply opacity-70 transition-opacity duration-200 hover:opacity-100;
> button {
@ -23,6 +23,6 @@
}
> hr {
@apply mx-3 h-5 w-0.5 bg-neutral-900/40 dark:bg-neutral-50/20;
@apply mx-3 h-5 w-0.5 bg-zinc-900/40 dark:bg-zinc-50/20;
}
}

View File

@ -12,7 +12,6 @@ import {
ZoomOut,
} from '@mui/icons-material';
import { ButtonBase, Divider, Tooltip, useMediaQuery, useTheme } from '@mui/material';
import clsx from 'clsx';
import dayjs from 'dayjs';
import get from 'lodash/get';
import { useTranslation } from 'next-i18next';
@ -26,6 +25,7 @@ import { printResumeAsPdf, PrintResumeAsPdfParams } from '@/services/printer';
import { togglePageBreakLine, togglePageOrientation, toggleSidebar } from '@/store/build/buildSlice';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import getResumeUrl from '@/utils/getResumeUrl';
import { cn } from '@/utils/styles';
import styles from './ArtboardController.module.scss';
@ -60,7 +60,7 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
const url = getResumeUrl(resume, { withHost: true });
await navigator.clipboard.writeText(url);
toast.success(t<string>('common.toast.success.resume-link-copied'));
toast.success(t('common.toast.success.resume-link-copied'));
};
const handleExportPDF = async () => {
@ -77,40 +77,40 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
return (
<div
className={clsx({
className={cn({
[styles.container]: true,
[styles.pushLeft]: left.open,
[styles.pushRight]: right.open,
})}
>
<div className={styles.controller}>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.undo')}>
<ButtonBase onClick={handleUndo} className={clsx({ 'pointer-events-none opacity-50': past.length < 2 })}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.undo')}>
<ButtonBase onClick={handleUndo} className={cn({ 'pointer-events-none opacity-50': past.length < 2 })}>
<UndoOutlined fontSize="medium" />
</ButtonBase>
</Tooltip>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.redo')}>
<ButtonBase onClick={handleRedo} className={clsx({ 'pointer-events-none opacity-50': future.length === 0 })}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.redo')}>
<ButtonBase onClick={handleRedo} className={cn({ 'pointer-events-none opacity-50': future.length === 0 })}>
<RedoOutlined fontSize="medium" />
</ButtonBase>
</Tooltip>
<Divider />
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.zoom-in')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.zoom-in')}>
<ButtonBase onClick={() => zoomIn(0.25)}>
<ZoomIn fontSize="medium" />
</ButtonBase>
</Tooltip>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.zoom-out')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.zoom-out')}>
<ButtonBase onClick={() => zoomOut(0.25)}>
<ZoomOut fontSize="medium" />
</ButtonBase>
</Tooltip>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.center-artboard')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.center-artboard')}>
<ButtonBase onClick={() => centerView(0.95)}>
<FilterCenterFocus fontSize="medium" />
</ButtonBase>
@ -120,10 +120,10 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
{isDesktop && (
<>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-orientation')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.toggle-orientation')}>
<ButtonBase
onClick={handleTogglePageOrientation}
className={clsx({ 'pointer-events-none opacity-50': pages.length === 1 })}
className={cn({ 'pointer-events-none opacity-50': pages.length === 1 })}
>
{orientation === 'vertical' ? (
<AlignHorizontalCenter fontSize="medium" />
@ -133,13 +133,13 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
</ButtonBase>
</Tooltip>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-page-break-line')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.toggle-page-break-line')}>
<ButtonBase onClick={handleTogglePageBreakLine}>
<InsertPageBreak fontSize="medium" />
</ButtonBase>
</Tooltip>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.toggle-sidebars')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.toggle-sidebars')}>
<ButtonBase onClick={handleToggleSidebar}>
<ViewSidebar fontSize="medium" />
</ButtonBase>
@ -149,13 +149,13 @@ const ArtboardController: React.FC<ReactZoomPanPinchHandlers> = ({ zoomIn, zoomO
</>
)}
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.copy-link')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.copy-link')}>
<ButtonBase onClick={handleCopyLink}>
<Link fontSize="medium" />
</ButtonBase>
</Tooltip>
<Tooltip arrow placement="top" title={t<string>('builder.controller.tooltip.export-pdf')}>
<Tooltip arrow placement="top" title={t('builder.controller.tooltip.export-pdf')}>
<ButtonBase onClick={handleExportPDF} disabled={isLoading}>
<Download fontSize="medium" />
</ButtonBase>

View File

@ -1,7 +1,7 @@
.center {
@apply mx-0 flex flex-grow pt-12 lg:pt-16;
@apply transition-[margin-left,margin-right] duration-200;
@apply bg-neutral-200 dark:bg-neutral-900;
@apply bg-zinc-100 dark:bg-zinc-900;
}
.wrapper {

View File

@ -1,9 +1,9 @@
import clsx from 'clsx';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';
import { useAppSelector } from '@/store/hooks';
import { cn } from '@/utils/styles';
import ArtboardController from './ArtboardController';
import styles from './Center.module.scss';
@ -19,7 +19,7 @@ const Center = () => {
if (isEmpty(resume)) return null;
return (
<div className={clsx(styles.center)}>
<div className={cn(styles.center)}>
<Header />
<TransformWrapper
@ -35,7 +35,7 @@ const Center = () => {
<>
<TransformComponent wrapperClass={styles.wrapper}>
<div
className={clsx({
className={cn({
[styles.artboard]: true,
'flex-col': orientation === 'vertical',
})}

View File

@ -1,10 +1,10 @@
.header {
@apply mx-0 flex justify-between shadow;
@apply bg-neutral-800 text-neutral-100;
@apply bg-zinc-900 text-zinc-100;
@apply transition-[margin-left,margin-right] duration-200;
button > svg {
@apply text-base text-neutral-100;
@apply text-base text-zinc-100;
}
}

View File

@ -20,7 +20,6 @@ import {
useMediaQuery,
useTheme,
} from '@mui/material';
import clsx from 'clsx';
import get from 'lodash/get';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
@ -37,6 +36,7 @@ import { setSidebarState, toggleSidebar } from '@/store/build/buildSlice';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setModalState } from '@/store/modal/modalSlice';
import getResumeUrl from '@/utils/getResumeUrl';
import { cn } from '@/utils/styles';
import styles from './Header.module.scss';
@ -102,7 +102,7 @@ const Header = () => {
},
},
},
})
}),
);
};
@ -132,14 +132,14 @@ const Header = () => {
const url = getResumeUrl(resume, { withHost: true });
await navigator.clipboard.writeText(url);
toast.success(t<string>('common.toast.success.resume-link-copied'));
toast.success(t('common.toast.success.resume-link-copied'));
};
return (
<AppBar elevation={0} position="fixed">
<Toolbar
variant="regular"
className={clsx({
className={cn({
[styles.header]: true,
[styles.pushLeft]: left.open,
[styles.pushRight]: right.open,
@ -165,14 +165,14 @@ const Header = () => {
<ListItemIcon>
<DriveFileRenameOutline className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.header.menu.rename')}</ListItemText>
<ListItemText>{t('builder.header.menu.rename')}</ListItemText>
</MenuItem>
<MenuItem onClick={handleDuplicate}>
<ListItemIcon>
<CopyAll className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.header.menu.duplicate')}</ListItemText>
<ListItemText>{t('builder.header.menu.duplicate')}</ListItemText>
</MenuItem>
{resume.public ? (
@ -180,27 +180,27 @@ const Header = () => {
<ListItemIcon>
<LinkIcon className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.header.menu.share-link')}</ListItemText>
<ListItemText>{t('builder.header.menu.share-link')}</ListItemText>
</MenuItem>
) : (
<Tooltip arrow placement="right" title={t<string>('builder.header.menu.tooltips.share-link')}>
<Tooltip arrow placement="right" title={t('builder.header.menu.tooltips.share-link')}>
<div>
<MenuItem>
<ListItemIcon>
<LinkIcon className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.header.menu.share-link')}</ListItemText>
<ListItemText>{t('builder.header.menu.share-link')}</ListItemText>
</MenuItem>
</div>
</Tooltip>
)}
<Tooltip arrow placement="right" title={t<string>('builder.header.menu.tooltips.delete')}>
<Tooltip arrow placement="right" title={t('builder.header.menu.tooltips.delete')}>
<MenuItem onClick={handleDelete}>
<ListItemIcon>
<Delete className="scale-90" />
</ListItemIcon>
<ListItemText>{t<string>('builder.header.menu.delete')}</ListItemText>
<ListItemText>{t('builder.header.menu.delete')}</ListItemText>
</MenuItem>
</Tooltip>
</Menu>

View File

@ -18,8 +18,8 @@
content: 'Page Break';
top: calc(297mm - 19px);
@apply absolute w-full border-b border-dashed border-neutral-800/75;
@apply flex items-end justify-end pr-2 pb-0.5 text-xs font-bold text-neutral-800/75;
@apply absolute w-full border-b border-dashed border-zinc-900/75;
@apply flex items-end justify-end pr-2 pb-0.5 text-xs font-bold text-zinc-900/75;
@apply print:hidden;
:global(.preview-mode) &,

View File

@ -49,9 +49,7 @@ const Page: React.FC<Props> = ({ page, showPageNumbers = false }) => {
{TemplatePage && <TemplatePage page={page} />}
</div>
{showPageNumbers && (
<h4 className={styles.pageNumber}>{`${t<string>('builder.common.glossary.page')} ${page + 1}`}</h4>
)}
{showPageNumbers && <h4 className={styles.pageNumber}>{`${t('builder.common.glossary.page')} ${page + 1}`}</h4>}
</div>
);
};