react-plaid-link icon indicating copy to clipboard operation
react-plaid-link copied to clipboard

Link does not clean up body style after Oauth

Open dwickander opened this issue 4 years ago • 13 comments

After an Oauth bank authentication (Platypus Oauth bank in sandbox) when returning to the receivedRedirectUri route using open() after selecting appropriate account and clicking continue, link closes the modal, but overflow: hidden is still set on the body. I have tried document.body.style.overflow ='visible' in an onExit function, but this does not change it either. If I authenticate with a bank that does not use the Oauth flow everthing works as expected and link cleans up the body style.

I am in sandbox mode and using react-plaid-link v 3.1.0.

dwickander avatar Apr 16 '21 16:04 dwickander

hello @dwickander are you able to provide code that reproduces this? I am unable to reproduce this in a test app. Code here: https://github.com/skylarmb/playground-react-plaid-link/tree/sb-test-body-overflow

https://user-images.githubusercontent.com/7543705/118196759-6c9b8d80-b402-11eb-9a32-70004c66b75f.mp4

skylarmb avatar May 13 '21 22:05 skylarmb

Oh I see you are using a slightly different integration method here... you are setting a redirect uri and re-initializing link on a new page and passing receivedRedirectUri to link... got it! I will have to test that method. The method shown above is with no redirect_uri so the OAuth just happens in a pop-over window

skylarmb avatar May 13 '21 23:05 skylarmb

Ok, i tested with a full redirect and I cant reproduce. Any tips on reproducing here here @dwickander ? Perhaps you are unmounting the Plaid Link component before it can do the cleanup? (however i tried this and it did not seem to have any effect)

Pushed code here: https://github.com/skylarmb/playground-react-plaid-link/tree/sb-test-body-overflow

https://user-images.githubusercontent.com/7543705/118199158-4a583e80-b407-11eb-802f-2a7142ea9add.mp4

skylarmb avatar May 13 '21 23:05 skylarmb

hey @dwickander any updates or guidance on how to reproduce this? otherwise I will close this issue soon

skylarmb avatar Jun 15 '21 00:06 skylarmb

@skylarmb Hi. I have the same problem. This is my code:

type PlaidProps = {
    submitHandler: typeof updateBankAccountAction | typeof postBankAccountAction;
    linkToken: string;
};

export const Plaid = (props: PlaidProps) => {
    const dispatch = useDispatch();
    const saveToken = useMemo(() => saveBankWidgetAccessTokenInFormAction, []);
    const accessToken = useSelector(selectBankWidgetAccessToken);

    const config: Parameters<typeof usePlaidLink>[0] = useMemo(
        () => ({
            token: props.linkToken,
            onSuccess: (token: string) => {
                dispatch(
                    saveToken({
                        saveData: {
                            providerName: BankProviderName.PLAID,
                            publicToken: token,
                        },
                        submitHandler: props.submitHandler,
                    }),
                );
            },
        }),
        [dispatch, props.linkToken, props.submitHandler, saveToken],
    );

    const { open, ready } = usePlaidLink(config);

    const openPlaid = useCallback(() => {
        if (ready) {
            open();
        }
    }, [open, ready]);

    useEffect(() => {
        console.log(accessToken);
    }, [accessToken]);

    return <>{openPlaid()}</>;
};

Plaid widget close automatically after onSuccess, but style overflow: hidden not removed from body tag

react-plaid-link: 3.2.0, plaid: 8.5.1, plaid-threads: 11.2.3,

IvanSavoskin avatar Jun 18 '21 09:06 IvanSavoskin

@skylarmb Hi. I have the same problem. This is my code:

type PlaidProps = {
    submitHandler: typeof updateBankAccountAction | typeof postBankAccountAction;
    linkToken: string;
};

export const Plaid = (props: PlaidProps) => {
    const dispatch = useDispatch();
    const saveToken = useMemo(() => saveBankWidgetAccessTokenInFormAction, []);
    const accessToken = useSelector(selectBankWidgetAccessToken);

    const config: Parameters<typeof usePlaidLink>[0] = useMemo(
        () => ({
            token: props.linkToken,
            onSuccess: (token: string) => {
                dispatch(
                    saveToken({
                        saveData: {
                            providerName: BankProviderName.PLAID,
                            publicToken: token,
                        },
                        submitHandler: props.submitHandler,
                    }),
                );
            },
        }),
        [dispatch, props.linkToken, props.submitHandler, saveToken],
    );

    const { open, ready } = usePlaidLink(config);

    const openPlaid = useCallback(() => {
        if (ready) {
            open();
        }
    }, [open, ready]);

    useEffect(() => {
        console.log(accessToken);
    }, [accessToken]);

    return <>{openPlaid()}</>;
};

Plaid widget close automatically after onSuccess, but style overflow: hidden not removed from body tag

react-plaid-link: 3.2.0, plaid: 8.5.1, plaid-threads: 11.2.3,

Did you check if this is creating a new accessToken when rendering the page or some other component rendering?

In my case I saw that I was creating accessToken more than one time and this was causing the overflow: hidden behavior.

johngrandson avatar Jul 07 '21 22:07 johngrandson

In case this helps anyone, here's how I fixed an issue I had with the scrollbar.

After connecting a new link, our app would render new PlaidLinks before closing the success dialog. PlaidLink saves the document.body styles that were present during construction. After closing the success dialog and going to another page, the component unmounts. PlaidLink resets the styles to overflow: hidden because there was no scrollbar when it rendered.

Instead of immediately rendering new PlaidLinks, we no longer immediately call our real callback. It's queued up until a HANDOFF event occurs.

pstoica avatar Jul 19 '21 22:07 pstoica

@pstoica thanks for this update! I actually did not personally know about this behavior of Link, so I appreciate your investigative work.

skylarmb avatar Jul 27 '21 17:07 skylarmb

hey all, I am going to close this. The conclusion here is that Link restores whatever style was on the body when it opened, so this is likely caused by having more than one Link instance on the page (for example opening a second instance before first instance closes completely) or some other library that is styling the body tag before Link launches, such as a modal or overlay.

Let me know if there are any further details that would suggest ^this is incorrect.

skylarmb avatar Aug 31 '21 16:08 skylarmb

When opening the Plaid modal while a Material UI modal is open, messing with the body style seems to screw up MUI's logic, which causes scroll to remain locked. What could help is simply being able to provide an option to the component or hook to disable side effects on the body styles. In this case the body's scroll is already locked when I am opening Plaid and so I do not need it to manage the document's style for me.

Being forced to work with this library's style side effects on the body just to open an iframe in a modal and nothing more seems overly strict and inflexible. This shouldn't be taken so lightly, messing with body styles is more likely to be destructive to an app's usability than a developer accidentally letting their users scroll a page behind a modal.

ScottMorse avatar Oct 22 '24 02:10 ScottMorse

I agree with @ScottMorse, especially because I have a repro where I don't even need to open the iframe to get it to break scrolling, also because my link is already in a modal. If it did overflow: hidden on the body only while the iframe was visible that'd be fine.

haubey avatar Feb 26 '25 20:02 haubey

Re-opening for the link team to look at.

BTW we now also have Hosted Link, which may be a workaround for some use cases where this causes problems: https://plaid.com/docs/link/hosted-link/

phoenixy1 avatar Feb 26 '25 22:02 phoenixy1

@phoenixy1 thanks for looking into it! I believe the code in question is in link-initialize.js, specifically

r.create = function create() {
            var t = document.body.style.overflow
              , r = null
              , o = !1
              , a = null
              , u = function hide() {
                o = !1,
                null != r && (r.style.display = "none"),
                document.body.style.overflow = t,
                window.parent.focus(),
                null != a && a.focus()
            };

where it resets the body's overflow style

haubey avatar Feb 26 '25 22:02 haubey