Skip to content

Security error when dispatching focus event on iOs #68

@MzelCiklum

Description

@MzelCiklum

Hello there! We've encountered a peculiar issue specifically on iOS (Safari 15+ and Chrome 132+) with our Frames React implementation when attempting to trigger a focus event within an iframe.

We are using the <Frames> component like this:

<Frames
    config={getFramesConfig(publicKey, style)}
    ready={() => onFramesReady(setIsFrameReady)}
    paymentMethodChanged={paymentMethodChanged(dispatchFrameAction)}
    frameValidationChanged={frameValidationChanged(dispatchFrameAction)}
    frameFocus={frameFocusChanged(dispatchFrameAction)}
    frameBlur={frameBlurChanged(dispatchFrameAction)}
>

The frameFocusChanged callback is defined as follows:

const frameFocusChanged =
    (dispatch: FrameActionDispatch) =>
    (frameElement: FrameElement | undefined) => {
        dispatch({ type: 'FOCUS', payload: frameElement?.element });
    };

On iOS devices (Safari 15+ and Chrome 132+), the dispatch event within frameFocusChanged is not being called. Instead, the following warning appears in the browser console:

SecurityError: Blocked a frame with origin "https://js.checkout.com" from accessing a cross-origin frame. Protocols, domains, and ports must match.

Interestingly, this issue is exclusively observed on iOS. The focus event and the subsequent dispatching work correctly on macOS Safari, Windows Safari, Chrome on other platforms (Windows, Android), and Firefox.

You can reproduce this issue by following these steps on an iOS device:

  • Navigate to https://demo-shop.test.avarda.com/cart/
  • Add any item to the cart.
  • Proceed to the cart URL.
  • Fill in the email and zip code fields (any random input should suffice).
  • Skip the SSN step if presented.
  • Select "Checkout.com" as the payment method.

Our implementation of the dispatch action and the relevant types are:

import { FrameElementIdentifer, PaymentMethod } from 'frames-react';

export type FrameStateAction =
    | {
          type: 'PAYMENT_METHOD_RECOGNIZED';
          payload: PaymentMethod;
      }
    | { type: 'PAYMENT_METHOD_UNKNOWN' }
    | {
          type: 'RESET_ELEMENT';
          payload: { element: FrameElementIdentifer; isEmpty: boolean };
      }
    | { type: 'ERROR'; payload: FrameElementIdentifer }
    | { type: 'FOCUS'; payload: FrameElementIdentifer | undefined }
    | { type: 'BLUR' };

export type FrameActionDispatch = React.Dispatch<FrameStateAction>;

We are currently using version 1.2.2 of frames-react.

The fact that this is isolated to iOS and accompanied by the SecurityError strongly suggests a potential issue with how the iframe from https://js.checkout.com is interacting with the parent frame (your application) specifically within the security context of iOS browsers. It seems the attempt to access frameElement?.element within the frameFocusChanged callback is being blocked by the browser's Same-Origin Policy on iOS, even though it works on other platforms.

Could you please investigate why this cross-origin access might be failing specifically on iOS and how we can resolve this issue to ensure the frameFocus event is correctly captured and dispatched on all platforms?

Thank you for your time and assistance!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions