From cf7a51ab8e51abc8504aa29bd4d466acd72de77d Mon Sep 17 00:00:00 2001 From: Jakub Majorek Date: Fri, 25 Mar 2022 13:39:09 +0100 Subject: [PATCH] Use sandbox on App iframe (#1893) * Use sandbox, handle external redirect * Add allow-same-origin flag * Update translations --- locale/defaultMessages.json | 3 ++ src/apps/components/AppFrame/AppFrame.tsx | 1 + src/apps/components/AppFrame/useAppActions.ts | 38 +++++++++++++++---- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index e81189a02..e5c0f3598 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -623,6 +623,9 @@ "context": "section header", "string": "About this app" }, + "src_dot_apps_dot_components_dot_AppFrame_dot_29277312": { + "string": "You are about to leave the Dashboard. Do you want to continue?" + }, "src_dot_apps_dot_components_dot_AppInProgressDeleteDialog_dot_1462011531": { "context": "dialog header", "string": "Delete App" diff --git a/src/apps/components/AppFrame/AppFrame.tsx b/src/apps/components/AppFrame/AppFrame.tsx index 2dbc20b42..5f8f39f31 100644 --- a/src/apps/components/AppFrame/AppFrame.tsx +++ b/src/apps/components/AppFrame/AppFrame.tsx @@ -54,6 +54,7 @@ export const AppFrame: React.FC = ({ onError={onError} onLoad={handleLoad} className={classes.iframe} + sandbox="allow-same-origin allow-forms allow-scripts" /> ); }; diff --git a/src/apps/components/AppFrame/useAppActions.ts b/src/apps/components/AppFrame/useAppActions.ts index 9ea5d690a..3e564cf63 100644 --- a/src/apps/components/AppFrame/useAppActions.ts +++ b/src/apps/components/AppFrame/useAppActions.ts @@ -1,6 +1,7 @@ import { Actions, DispatchResponseEvent, Events } from "@saleor/app-bridge"; import useNavigator from "@saleor/hooks/useNavigator"; import React from "react"; +import { useIntl } from "react-intl"; import { useExternalApp } from "../ExternalAppContext"; @@ -21,6 +22,7 @@ export const useAppActions = ( ) => { const navigate = useNavigator(); const { closeApp } = useExternalApp(); + const intl = useIntl(); const actionReducer = ( action: Actions | undefined @@ -29,16 +31,36 @@ export const useAppActions = ( case "redirect": { const { to, newContext, actionId } = action.payload; - if (newContext) { - window.open(to); - } else if (to.startsWith("/")) { - navigate(to); - closeApp(); - } else { - window.location.href = to; + let success = true; + + try { + if (newContext) { + window.open(to); + } else if (to.startsWith("/")) { + navigate(to); + closeApp(); + } else { + const isExternalDomain = + new URL(to).hostname !== window.location.hostname; + + if (isExternalDomain) { + success = window.confirm( + intl.formatMessage({ + defaultMessage: + "You are about to leave the Dashboard. Do you want to continue?" + }) + ); + } + + if (success) { + window.location.href = to; + } + } + } catch (e) { + success = false; } - return sendResponseStatus(actionId, true); + return sendResponseStatus(actionId, success); } default: { return sendResponseStatus(action?.payload?.actionId, false);