CollaboraOnline / online

Collabora Online is a collaborative online office suite based on LibreOffice technology. This is also the source for the Collabora Office apps for iOS and Android.
https://collaboraonline.com
Other
1.85k stars 701 forks source link

No PostMessags when running on different Domains #2380

Open rsoika opened 3 years ago

rsoika commented 3 years ago

Sorry for opening a Bugreport but for the following problem there seems to be no clear answer anywhere in the documentation of Collabora.

I have implemented a WOPI Host to integrate Collabora into my Web Application. On my developer environment everything is working fine. I also wrote a short blogspot about how to implement a Wopi Host in java. And I think I have a good understanding about the concepts.

But now, as I tried to setup all my stuff in a productive Kubernetes cluster, I come to the problem with the different domains. All the relevant discussion in the Internet is about specify applications like OwnCloud, NextCloud... . But I did not found a clear answer which settings are relevant in Collabora if it runs in a different domain as the web app.

Concrete the problem is, that when the editor is loaded in the iframe, no PostMessages arive. And I can't figure out why. I invested serveral hours to avoid this Bug report - but with no success ;-)

I am running the Docker Image collabora/code:6.4.8.4. Form the general setup everything seems to be ok. If I debug the system, I can see that

  1. Collabora is requestin the CheckFileInfo
  2. my WopiHost is answering the request
  3. Collabora is exaiming the json object successfully and requests the File contents
  4. my WopiHost is answering the request

But now the Editor in the iframe get stuck.

image

And the only message I can assign to the problem is the following javaScipt error in the browser:

Uncaught TypeError: map.options.docParams is undefined
    connect http://libreoffice.foo.muc:9980/loleaflet/6a844e4/bundle.js:1
    loadDocument http://libreoffice.foo.muc:9980/loleaflet/6a844e4/bundle.js:1
    <anonymous> http://libreoffice.foo.muc:9980/loleaflet/6a844e4/bundle.js:1
    <anonymous> http://libreoffice.foo.muc:9980/loleaflet/6a844e4/bundle.js:1
    <anonymous> http://libreoffice.foo.muc:9980/loleaflet/6a844e4/bundle.js:1

In detail the corresponding part in the bundle.js is:

        connect: function(socket) {
            var map = this._map;
            if (map.options.permission) {
                map.options.docParams["permission"] = map.options.permission   // !!!! cannot set property 'permission' of undefined
            }

The bit question for me is what environment settings should I use for the Docker container and how should the loolwsd.xml file be tweaked?

How should the docker environment variables look like? I am using a docker setup like this:

  libreoffice-app:
    image: collabora/code:6.4.8.4
    container_name: libreoffice-app
    environment:
      username: "admin"
      password: "adminadmin"
      extra_params: "--o:ssl.enable=false"
      domain: "libreoffice.foo.muc:9980"
    expose:
      - 9980
    ports:
      - "9980:9980"
    volumes:
      - ./configuration/collabora/loolwsd.xml:/etc/loolwsd/loolwsd.xml

What does the environment variable 'domain' realy is for? Should the port number be part of it?

And than there is the loolwsd.xml file

I tried to set the following custom settings:

....
 <net>
  ....
  <post_allow desc="Allow/deny client IP address for POST(REST)." allow="true">
    ...
    <host desc="wildcard" allow="true">.*\.foo\.muc</host>
    ...
   </post_allow>
  <frame_ancestors>application.foo.muc:8080</frame_ancestors>
  </net>
  ....
  <storage desc="Backend storage">
   ....
   <wopi desc="Allow/deny wopi storage. Mutually exclusive with webdav." allow="true">
   ....
       <host desc="wildcard" allow="true">.*\.foo\.muc</host>
    ...
   </storage>

I think I have already tried any kind of combination the last several hours.

Just to note: If I run all on localhost everything is working.

Can you help me out from my current configuration hell ? Can you explain what the JavaScript Meessage TypeError: map.options.docParams is undefined tries to tell me?

Maybe there is a way to improve the logging inside the bundle.js ?

rsoika commented 3 years ago

I narrowed down the problem a little bit. And a come to this part of the bundle.js:

(function(global) {
    var wopiParams;
    var wopiSrc = getParameterByName("WOPISrc");
    if (wopiSrc !== "" && accessToken !== "") {
        wopiParams = {
            access_token: accessToken,
            access_token_ttl: accessTokenTTL
        }
    } else if (wopiSrc !== "" && accessHeader !== "") {
        wopiParams = {
            access_header: accessHeader
        }
    }
    if (reuseCookies !== "") {
        if (wopiParams) {
            wopiParams["reuse_cookies"] = reuseCookies
        } else {
            wopiParams = {
                reuse_cookies: reuseCookies
            }
        }
    }

My wopiSrc looks like this:

"http://app:8080/api/wopi/8d5d845b-d02d-4e14-b585-c1c5a9f8e36e/files/imixs-workflow.odt?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2MjEwODEyNjksInN1YiI6IndvcGktaG9zdCIsInVzZXJpZCI6InJzb2lrYSIsInVzZXJuYW1lIjoiUmFscGggU29pa2EifQ.qJhgVoWf4cbI7_Yl1zrzkUJi8QWtK5kc3Qmi3yYPT_k"

As a result the variable 'wopiParams' will never be set. Can this be the root of the problem?

rsoika commented 3 years ago

I continued my analysis but without any success

When I set loleaflet_logging to true (in the loolwsd.xml file) I can see the following error message on the server console:

kit-00045-00039 2021-05-16 09:20:31.220363 [ kitbroker_001 ] INF  Created new view with viewid: [0] for username: [Ralph Soika] in session: [004].| kit/ChildSession.cpp:639
kit-00045-00039 2021-05-16 09:20:31.220377 [ kitbroker_001 ] DBG  Sending status after loading view 0.| kit/ChildSession.cpp:678
kit-00045-00039 2021-05-16 09:20:31.220565 [ kitbroker_001 ] INF  Loaded session 004| kit/ChildSession.cpp:691
wsd-00007-00046 2021-05-16 09:20:34.076371 [ docbroker_001 ] ERR  jserror {
  "userAgent": "mozilla/5.0 (x11; linux x86_64; rv:78.0) gecko/20100101 firefox/78.0",
  "vendor": "",
  "message": "TypeError: map.options.docParams is undefined",
  "source": "https://libreoffice.foo.com/loleaflet/6a844e4/bundle.js",
  "line": 1,
  "column": 998960
}
map.options.docParams is undefined
connect@https://libreoffice.foo.com/loleaflet/6a844e4/bundle.js:1:998960
loadDocument@https://libreoffice.foo.com/loleaflet/6a844e4/bundle.js:1:1056611
@https://libreoffice.foo.com/loleaflet/6a844e4/bundle.js:1:2440468
@https://libreoffice.foo.com/loleaflet/6a844e4/bundle.js:1:2440731
@https://libreoffice.foo.com/loleaflet/6a844e4/bundle.js:1:2440741
| wsd/ClientSession.cpp:395

Also from the debugging the bundle.js I can see that docParms is always undefined.

What could be the reason for this?

rsoika commented 3 years ago

I found a very ugly workaround.

During loading my application I set a top-level domain cookie with a dummy value

  document.cookie = "wopi_dummy=true;expires=" + expireDate + ";domain=.foo.com;path=/";

With this trick the bundle.js is happy and the resolving of the wopi params worked.

I think the code I identified above should look something like this:


    var wopiParams;
    var wopiSrc = getParameterByName("WOPISrc");
    if (wopiSrc !== "" && accessToken !== "") {
        wopiParams = {
            access_token: accessToken,
            access_token_ttl: accessTokenTTL
        }
    } else if (wopiSrc !== "" && accessHeader !== "") {
        wopiParams = {
            access_header: accessHeader
        }
    }
    if (reuseCookies !== "") {
        if (wopiParams) {
            wopiParams["reuse_cookies"] = reuseCookies
        } else {
            wopiParams = {
                reuse_cookies: reuseCookies
            }
        }
    }
    // do we have wopParams?
    if (!wopiParams) { // undefined
        wopiParams={};
    }

But I am not the JavaScript expert so maybe you found a better solution.

I also thinks that this topic is related to the issues #2302 and the commit https://github.com/CollaboraOnline/online/commit/8f4fd370c575c65e62ed4ff6a5f55e3b22c9e33a

rsoika commented 3 years ago

Hello, I still struggle with this kind of issue - in cases of different domains some of my users run into the JavaScript problem

map.options.docParams is undefined

I can not figure out the real reason, and I need some help to get deeper into the cause of the problem.

rsoika commented 3 years ago

Once again I run into this problem. To get rid of the problem the only chance seems to be to set a top-level domain cookie within the web application providing the iframe with collabora.

When the page is loaded I run a script like this:

// jquery code example
$(document).ready(function() {
    var expireDate = new Date();
    expireDate.setHours(expireDate.getHours() + 24);    
    var topDomain=window.location.hostname;
    var domainParts = topDomain.split('.');
    if (domainParts && domainParts.length>1) {
       topDomain='.'+domainParts[domainParts.length-2] +'.'+domainParts[domainParts.length-1];
    }
    document.cookie = "wopi_dummy=true;expires=" + expireDate 
                      + ";domain=" + topDomain+";path=/";
});

This code sets a dummy-cookie for the top level domain. For example, in the situation you run collabora and the web application in the two domains:

the cookie with the name 'wopi_dummy' is set in the domain 'foo.com'

Only in this case the java script I mentioned earlier in this post, will succeed (see my post from the 15 and 17 may).

Also I guess that OwnCloud (which seems to be the main adapter of Collabora) is setting some cookies for other reasons and they did not run into the problem at all.

Can someone comment this topic? I really invested a lot of time to improve Collabora and I hope to get some kind of feedback.

Darshan-upadhyay1110 commented 5 days ago

Hello @rsoika does this issue still reproducible ?