From a5e75cffca58ec2fc911b592f003d55929091efa Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Mon, 27 Mar 2023 19:23:10 +0300 Subject: [PATCH 1/6] add confirmation --- .../app/containers/Admin/Buckets/Buckets.tsx | 71 ++++++++++++++----- catalog/app/containers/Admin/Form.tsx | 4 +- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/catalog/app/containers/Admin/Buckets/Buckets.tsx b/catalog/app/containers/Admin/Buckets/Buckets.tsx index d1bc9322765..f08818a6343 100644 --- a/catalog/app/containers/Admin/Buckets/Buckets.tsx +++ b/catalog/app/containers/Admin/Buckets/Buckets.tsx @@ -11,6 +11,7 @@ import * as M from '@material-ui/core' import * as Lab from '@material-ui/lab' import BucketIcon from 'components/BucketIcon' +import * as Dialog from 'components/Dialog' import * as Pagination from 'components/Pagination' import Skeleton from 'components/Skeleton' import * as Notifications from 'containers/Notifications' @@ -81,6 +82,57 @@ const integerInRange = (min: number, max: number) => (v: string | null | undefin return undefined } +function PFSCheckbox({ input, meta }: Form.CheckboxProps & M.CheckboxProps) { + const confirm = React.useCallback((checked) => input?.onChange(checked), [input]) + const dialog = Dialog.useConfirm({ + title: + 'You are about to enable JavaScript execution and data access in iframe previews of HTML files', + onSubmit: confirm, + }) + const handleCheckbox = React.useCallback( + (event: React.ChangeEvent, checked: boolean) => { + if (checked) { + dialog.open() + } else { + input?.onChange(checked) + } + }, + [dialog, input], + ) + return ( + <> + {dialog.render( + + Warning: you must only enable this feature for buckets with trusted contents. + Failure to heed this warning may result in breach of sensitive data. + , + )} + + } + label={ + <> + Enable permissive HTML rendering + + This allows execution of any JavaScript code and fetching network resources + relative to package. But beware, the iframe with rendered HTML (and package + resources) can be shared publicly during session lifespan. Session is active + while the page with rendered HTML is opened. +
+ Enable only on trusted buckets. +
+ + } + /> + + ) +} + const editFormSpec: FormSpec = { title: R.pipe( R.prop('title'), @@ -648,24 +700,7 @@ function BucketFields({ bucket, reindex }: BucketFieldsProps) { File preview options - - Enable permissive HTML rendering - - This allows execution of any JavaScript code and fetching network - resources relative to package. But beware, the iframe with rendered HTML - (and package resources) can be shared publicly during session lifespan. - Session is active while the page with rendered HTML is opened. -
- Enable only on trusted buckets. -
- - } - /> +
diff --git a/catalog/app/containers/Admin/Form.tsx b/catalog/app/containers/Admin/Form.tsx index 1a6da17bcaf..2d9e8ccb66a 100644 --- a/catalog/app/containers/Admin/Form.tsx +++ b/catalog/app/containers/Admin/Form.tsx @@ -36,11 +36,11 @@ const useCheckboxStyles = M.makeStyles({ }, }) -interface CheckboxProps { +export interface CheckboxProps { errors?: Record input?: RF.FieldInputProps meta: RF.FieldMetaState - label?: string + label?: React.ReactNode FormControlLabelProps?: M.FormControlLabelProps } From 7c169835dd756e74cf2179b097bc112d821aac57 Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Mon, 27 Mar 2023 19:28:29 +0300 Subject: [PATCH 2/6] custom cancel and submit titles --- catalog/app/components/Dialog/Confirm.tsx | 21 +++++++++++++++---- .../app/containers/Admin/Buckets/Buckets.tsx | 3 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/catalog/app/components/Dialog/Confirm.tsx b/catalog/app/components/Dialog/Confirm.tsx index 5ccf067de4e..69db1686a8b 100644 --- a/catalog/app/components/Dialog/Confirm.tsx +++ b/catalog/app/components/Dialog/Confirm.tsx @@ -3,13 +3,22 @@ import * as React from 'react' import * as M from '@material-ui/core' interface DialogProps { + cancelTitle?: string children: React.ReactNode onSubmit: (value: boolean) => void open: boolean + submitTitle?: string title: string } -function Dialog({ children, onSubmit, open, title }: DialogProps) { +function Dialog({ + children, + onSubmit, + open, + cancelTitle = 'Cancel', + submitTitle = 'Submit', + title, +}: DialogProps) { const handleCancel = React.useCallback(() => onSubmit(false), [onSubmit]) const handleSubmit = React.useCallback(() => onSubmit(true), [onSubmit]) return ( @@ -18,10 +27,10 @@ function Dialog({ children, onSubmit, open, title }: DialogProps) { {children} - Cancel + {cancelTitle} - Submit + {submitTitle} @@ -29,11 +38,13 @@ function Dialog({ children, onSubmit, open, title }: DialogProps) { } interface PromptProps { + cancelTitle?: string onSubmit: (value: boolean) => void + submitTitle?: string title: string } -export function useConfirm({ title, onSubmit }: PromptProps) { +export function useConfirm({ cancelTitle, title, onSubmit, submitTitle }: PromptProps) { const [key, setKey] = React.useState(0) const [opened, setOpened] = React.useState(false) const open = React.useCallback(() => { @@ -52,10 +63,12 @@ export function useConfirm({ title, onSubmit }: PromptProps) { (children: React.ReactNode) => ( diff --git a/catalog/app/containers/Admin/Buckets/Buckets.tsx b/catalog/app/containers/Admin/Buckets/Buckets.tsx index f08818a6343..dc8cdde7366 100644 --- a/catalog/app/containers/Admin/Buckets/Buckets.tsx +++ b/catalog/app/containers/Admin/Buckets/Buckets.tsx @@ -85,12 +85,13 @@ const integerInRange = (min: number, max: number) => (v: string | null | undefin function PFSCheckbox({ input, meta }: Form.CheckboxProps & M.CheckboxProps) { const confirm = React.useCallback((checked) => input?.onChange(checked), [input]) const dialog = Dialog.useConfirm({ + submitTitle: 'I agree', title: 'You are about to enable JavaScript execution and data access in iframe previews of HTML files', onSubmit: confirm, }) const handleCheckbox = React.useCallback( - (event: React.ChangeEvent, checked: boolean) => { + (event, checked: boolean) => { if (checked) { dialog.open() } else { From f2baa58222a88c869d1b6d3be31b2cd24b2406b2 Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Mon, 27 Mar 2023 19:42:18 +0300 Subject: [PATCH 3/6] linting and styling --- catalog/app/components/Dialog/Confirm.tsx | 2 +- catalog/app/containers/Admin/Buckets/Buckets.tsx | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/catalog/app/components/Dialog/Confirm.tsx b/catalog/app/components/Dialog/Confirm.tsx index 69db1686a8b..15d1749d709 100644 --- a/catalog/app/components/Dialog/Confirm.tsx +++ b/catalog/app/components/Dialog/Confirm.tsx @@ -73,7 +73,7 @@ export function useConfirm({ cancelTitle, title, onSubmit, submitTitle }: Prompt }} /> ), - [key, handleSubmit, opened, title], + [cancelTitle, key, handleSubmit, opened, title, submitTitle], ) return React.useMemo( () => ({ diff --git a/catalog/app/containers/Admin/Buckets/Buckets.tsx b/catalog/app/containers/Admin/Buckets/Buckets.tsx index dc8cdde7366..871ac101bc4 100644 --- a/catalog/app/containers/Admin/Buckets/Buckets.tsx +++ b/catalog/app/containers/Admin/Buckets/Buckets.tsx @@ -82,7 +82,14 @@ const integerInRange = (min: number, max: number) => (v: string | null | undefin return undefined } +const usePFSCheckboxStyles = M.makeStyles({ + root: { + marginBottom: -9, + marginTop: -9, + }, +}) function PFSCheckbox({ input, meta }: Form.CheckboxProps & M.CheckboxProps) { + const classes = usePFSCheckboxStyles() const confirm = React.useCallback((checked) => input?.onChange(checked), [input]) const dialog = Dialog.useConfirm({ submitTitle: 'I agree', @@ -111,6 +118,7 @@ function PFSCheckbox({ input, meta }: Form.CheckboxProps & M.CheckboxProps) { Date: Mon, 27 Mar 2023 19:46:50 +0300 Subject: [PATCH 4/6] add changelog entry --- docs/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 08a10afd0db..1d3b72b8f0e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -21,6 +21,7 @@ Entries inside each section should be ordered by type: * [Added] Add basic support for tasklist in Markdown ([#3339](https://github.com/quiltdata/quilt/pull/3339)) * [Added] Object-level validation, frontend ([#3336](https://github.com/quiltdata/quilt/pull/3336)) * [Added] Frontend for permissive HTML rendering ([#3198](https://github.com/quiltdata/quilt/pull/3198)) +* [Added] Confirmation to enable Package Files Server ([#3388](https://github.com/quiltdata/quilt/pull/3388)) * [Fixed] Fixed mobile layout for collaborators badges ([#3307](https://github.com/quiltdata/quilt/pull/3307)) * [Fixed] Fixed metadata handling for entries without hash or size in pkgpush lambda ([#3314](https://github.com/quiltdata/quilt/pull/3314)) * [Fixed] Fixed adding metadata for S3 entries ([#3367]https://github.com/quiltdata/quilt/pull/3367) From 54be7ec11ab5b91c49e60a3ab730cd39adab34c1 Mon Sep 17 00:00:00 2001 From: Maksim Chervonnyi Date: Mon, 27 Mar 2023 20:12:37 +0300 Subject: [PATCH 5/6] Update catalog/app/containers/Admin/Buckets/Buckets.tsx Co-authored-by: Rob Newman <61608+robnewman@users.noreply.github.com> --- catalog/app/containers/Admin/Buckets/Buckets.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/catalog/app/containers/Admin/Buckets/Buckets.tsx b/catalog/app/containers/Admin/Buckets/Buckets.tsx index 871ac101bc4..a1204a9d461 100644 --- a/catalog/app/containers/Admin/Buckets/Buckets.tsx +++ b/catalog/app/containers/Admin/Buckets/Buckets.tsx @@ -128,12 +128,12 @@ function PFSCheckbox({ input, meta }: Form.CheckboxProps & M.CheckboxProps) { <> Enable permissive HTML rendering - This allows execution of any JavaScript code and fetching network resources - relative to package. But beware, the iframe with rendered HTML (and package - resources) can be shared publicly during session lifespan. Session is active - while the page with rendered HTML is opened. + This allows execution of any linked JavaScript code and fetching network resources + relative to the package. Be aware that the iframe with rendered HTML (and package + resources) can be shared publicly during the session lifespan. The session is active + while the page with rendered HTML is open.
- Enable only on trusted buckets. + Enable only on trusted AWS S3 buckets.
} From 86c088abd1aaf3fe39d8392f3320c7ae8795aece Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Mon, 27 Mar 2023 20:15:41 +0300 Subject: [PATCH 6/6] prettify --- catalog/app/containers/Admin/Buckets/Buckets.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/catalog/app/containers/Admin/Buckets/Buckets.tsx b/catalog/app/containers/Admin/Buckets/Buckets.tsx index a1204a9d461..32efc35c696 100644 --- a/catalog/app/containers/Admin/Buckets/Buckets.tsx +++ b/catalog/app/containers/Admin/Buckets/Buckets.tsx @@ -128,10 +128,10 @@ function PFSCheckbox({ input, meta }: Form.CheckboxProps & M.CheckboxProps) { <> Enable permissive HTML rendering - This allows execution of any linked JavaScript code and fetching network resources - relative to the package. Be aware that the iframe with rendered HTML (and package - resources) can be shared publicly during the session lifespan. The session is active - while the page with rendered HTML is open. + This allows execution of any linked JavaScript code and fetching network + resources relative to the package. Be aware that the iframe with rendered + HTML (and package resources) can be shared publicly during the session + lifespan. The session is active while the page with rendered HTML is open.
Enable only on trusted AWS S3 buckets.