Open robmoffat opened 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.
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
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.