diff --git a/browser/html/cool.html.m4 b/browser/html/cool.html.m4 index 1e28026e4611c..cdefe50b715b0 100644 --- a/browser/html/cool.html.m4 +++ b/browser/html/cool.html.m4 @@ -254,6 +254,7 @@ m4_ifelse(MOBILEAPP, [true], data-saved-ui-state = "%SAVED_UI_STATE%" data-wasm-enabled = "%WASM_ENABLED%" data-indirection-url = "%INDIRECTION_URL%" + data-geolocation-setup = "%GEOLOCATION_SETUP%" /> ]) diff --git a/browser/js/global.js b/browser/js/global.js index a706aa247276c..b16c7c82d386d 100644 --- a/browser/js/global.js +++ b/browser/js/global.js @@ -288,6 +288,7 @@ class InitializerBase { window.savedUIState = true; window.wasmEnabled = false; window.indirectionUrl = ""; + window.geolocationSetup = false; window.tileSize = 256; @@ -406,6 +407,7 @@ class BrowserInitializer extends InitializerBase { window.savedUIState = element.dataset.savedUiState.toLowerCase().trim() === "true"; window.wasmEnabled = element.dataset.wasmEnabled.toLowerCase().trim() === "true"; window.indirectionUrl = element.dataset.indirectionUrl; + window.geolocationSetup = element.dataset.geolocationSetup.toLowerCase().trim() === "true"; } postMessageHandler(e) { @@ -1385,54 +1387,63 @@ function getInitializerClass() { global.parent.postMessage(JSON.stringify(msg), '*'); }; - var http = new XMLHttpRequest(); - let url = global.indirectionUrl + '?Uri=' + encodeURIComponent(that.uri); - http.open('GET', url, true); - http.responseType = 'json'; - http.addEventListener('load', function() { - if (this.status === 200) { - var uriWithRouteToken = http.response.uri; - global.expectedServerId = http.response.serverId; - var params = (new URL(uriWithRouteToken)).searchParams; - global.routeToken = params.get('RouteToken'); - global.app.console.log('updated routeToken: ' + global.routeToken); - that.innerSocket = new WebSocket(uriWithRouteToken); - that.innerSocket.binaryType = that.binaryType; - that.innerSocket.onerror = function() { - that.readyState = that.innerSocket.readyState; - that.onerror(); - }; - that.innerSocket.onclose = function() { - that.readyState = 3; - that.onclose(); - that.innerSocket.onerror = function () {}; - that.innerSocket.onclose = function () {}; - that.innerSocket.onmessage = function () {}; - }; - that.innerSocket.onopen = function() { - that.readyState = 1; - that.onopen(); - }; - that.innerSocket.onmessage = function(e) { - that.readyState = that.innerSocket.readyState; - that.onmessage(e); - }; - } else if (this.status === 202) { - if (!(window.app && window.app.socket && window.app.socket._reconnecting)) { + this.sendRouteTokenRequest = function (requestUri) { + var http = new XMLHttpRequest(); + // let url = global.indirectionUrl + '?Uri=' + encodeURIComponent(that.uri); + http.open('GET', requestUri, true); + http.responseType = 'json'; + http.addEventListener('load', function () { + if (this.status === 200) { + var uriWithRouteToken = http.response.uri; + global.expectedServerId = http.response.serverId; + var params = (new URL(uriWithRouteToken)).searchParams; + global.routeToken = params.get('RouteToken'); + global.app.console.log('updated routeToken: ' + global.routeToken); + that.innerSocket = new WebSocket(uriWithRouteToken); + that.innerSocket.binaryType = that.binaryType; + that.innerSocket.onerror = function () { + that.readyState = that.innerSocket.readyState; + that.onerror(); + }; + that.innerSocket.onclose = function () { + that.readyState = 3; + that.onclose(); + that.innerSocket.onerror = function () { }; + that.innerSocket.onclose = function () { }; + that.innerSocket.onmessage = function () { }; + }; + that.innerSocket.onopen = function () { + that.readyState = 1; + that.onopen(); + }; + that.innerSocket.onmessage = function (e) { + that.readyState = that.innerSocket.readyState; + that.onmessage(e); + }; + } else if (this.status === 202) { + if (!(window.app && window.app.socket && window.app.socket._reconnecting)) { that.sendPostMsg(http.response.errorCode); + } + var timeoutFn = function (requestUri) { + console.warn('Requesting again for routeToken'); + this.open('GET', requestUri, true); + this.send(); + }.bind(this); + setTimeout(timeoutFn, 3000, requestUri); + } else { + global.app.console.error('Indirection url: error on incoming response ' + this.status); + that.sendPostMsg(-1); } - var timeoutFn = function (indirectionUrl, uri) { - console.warn('Requesting again for routeToken'); - this.open('GET', indirectionUrl + '?Uri=' + encodeURIComponent(uri), true); - this.send(); - }.bind(this); - setTimeout(timeoutFn, 3000, global.indirectionUrl, that.uri); - } else { - global.app.console.error('Indirection url: error on incoming response ' + this.status); - that.sendPostMsg(-1); - } - }); - http.send(); + }); + http.send(); + }; + + let requestUri = global.indirectionUrl + '?Uri=' + encodeURIComponent(that.uri); + if (global.geolocationSetup) { + let timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; + requestUri += "&TimeZone=" + timeZone; + } + this.sendRouteTokenRequest(requestUri); }; global.createWebSocket = function(uri) { diff --git a/coolwsd.xml.in b/coolwsd.xml.in index 6f18d815fd8a8..dfae6e60a07c3 100644 --- a/coolwsd.xml.in +++ b/coolwsd.xml.in @@ -322,6 +322,9 @@ + + false + @LOCK_CONFIGURATION@ diff --git a/wsd/ClientRequestDispatcher.cpp b/wsd/ClientRequestDispatcher.cpp index 3e130c8a60dd1..88db2864c8431 100644 --- a/wsd/ClientRequestDispatcher.cpp +++ b/wsd/ClientRequestDispatcher.cpp @@ -2002,6 +2002,27 @@ std::string ClientRequestDispatcher::getDiscoveryXML() #if !MOBILEAPP +/// Get IANA timezone name +static std::string getIANATimezone() +{ + const char* tzfile = "/etc/localtime"; + char buf[PATH_MAX]; + + ssize_t len = readlink(tzfile, buf, sizeof(buf) - 1); + if (len != -1) + { + buf[len] = '\0'; + std::string fullPath(buf); + + std::string prefix = "../usr/share/zoneinfo/"; + if (fullPath.substr(0, prefix.size()) == prefix) + { + return fullPath.substr(prefix.size()); + } + } + return std::string(); +} + /// Create the /hosting/capabilities JSON and return as string. static std::string getCapabilitiesJson(bool convertToAvailable) { @@ -2054,6 +2075,15 @@ static std::string getCapabilitiesJson(bool convertToAvailable) if (const char* podName = std::getenv("POD_NAME")) capabilities->set("podName", podName); + bool geoLocationSetup = + config::getBool(std::string("indirection_endpoint.geolocation_setup.enable"), false); + if (geoLocationSetup) + { + std::string timezoneName = getIANATimezone(); + if (!timezoneName.empty()) + capabilities->set("timezone", std::string(timezoneName)); + } + std::ostringstream ostrJSON; capabilities->stringify(ostrJSON); return ostrJSON.str(); diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 6de6544e29396..32ca3ebf3a253 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -1366,6 +1366,11 @@ FileServerRequestHandler::ResourceAccessDetails FileServerRequestHandler::prepro Poco::URI indirectionURI(config.getString("indirection_endpoint.url", "")); Poco::replaceInPlace(preprocess, std::string("%INDIRECTION_URL%"), indirectionURI.toString()); + bool geoLocationSetup = config.getBool("indirection_endpoint.geolocation_setup.enable"); + if (geoLocationSetup) + Poco::replaceInPlace(preprocess, std::string("%GEOLOCATION_SETUP%"), + boolToString(geoLocationSetup)); + const std::string mimeType = "text/html"; // Document signing: if endpoint URL is configured, whitelist that for