finos / FDC3

An open standard for the financial desktop.
https://fdc3.finos.org
Other
202 stars 132 forks source link

Address Session Storage issue in FDC3 for the web for same domain iframes in a parent window #1430

Open robmoffat opened 1 week ago

robmoffat commented 1 week ago

The implementation work for FDC3 for the Web identified a problem with the use of Session Storage for saving instanceId / instanceUuid: where iframes are used to display apps within the parent window (a common use case for FDC3 for the Web) and theey are on the same domain, they share a Session Storage instance and will overwrite each others data.

An adjustment to the proposed session storage use is needed to ensure that Session Storage for same-domain iframes doesn't collide.

kriswest commented 1 week ago

The proposed solution is to make use of window names (window.name) to namespace the data stored in SessionStorage replacing the fixed name key that is currently used. Window names can be applied by either the parent window or code running inside the window, hence, a Desktop agent can apply a name when creating an iframe or the getAgent implementation can generate and apply a unique name if it doesn't find one at window.name.

Window names persist through navigation events on the same domain (not same origin). Browser will usually delete the name if you navigate off domain, and restore it if you navigate back. This should make window.name appropriate for namespaces, as the data does not need to be retrieved / cannot be retrieved (for multiple reasons) when the window is pointing at a different domain or origin.

We also need to store information for multiple apps and access it before we know the appId (as this is assigned and validated by the Desktop Agent). The identityUrl is used to identify appId, hence, the data also needs to be namespaced by identityUrl as it is intended that a window should be able to navigate and become a different app, then navigate back and become the original app again. This is handled by SessionStorage when the apps are on different origins (as SessionStorage is scoped by origin) but not when navigating within an origin (which can host multiple apps at different paths).

Hence, the proposal is to store the DesktopAgentDetails for each app under a key based on the window name (e.g. `FDC3-Desktop-Agent-Details-${window.name}`) and to store it as an object with the identityUrl as the key.

E.g. if we had loaded 2 apps with identityUrls https://mydomain/app1 and https://mydomain/app2 in different iframes in one parent window with names win1 and win2, then navigated win1 to become https://mydomain/app3 AND all apps were same origin then we would have in storage:

{ // n.b. this level isn't really an object but SessionStorage itself

    "FDC3-Desktop-Agent-Details-win1": {
        "https://mydomain/app1": { ...DesktopAgentDetails },
        "https://mydomain/app3": { ... DesktopAgentDetails }
    },

    "FDC3-Desktop-Agent-Details-win2": {
        "https://mydomain/app2": { ...DesktopAgentDetails }
    }

}

@novavi @robmoffat I believe this would prevent all clashes and ensures that differnet windows are writing to different keys in SessionStorage (in case they happened to do so concurrently, eg. because the parent window was reloaded). Data for different apps that have been loaded in the same window would not be written at the same time (as the iframe can only point to one URL at a time) but the code would need to retrieve and preserve data for other apps.

If this works for you can either start work on trying to do this in the implementation OR in the documentation. As we want to get docs signed off and merged ASAP I suspect I should do the latter first.

robmoffat commented 1 week ago

Hi @kriswest,

The current implementation of this is isolated in a single class, AbstractWebMessaging

So you should be able to have a play and come up with something you like. There are also tests: "Recover from SessionState" and "Failed Recovery from SessionState" inside the destop-agent-strategy.feature file