Skip to content

Commit

Permalink
Exposed leeway setting in the JWT library
Browse files Browse the repository at this point in the history
If the system clock of the document server is even a second slower than the
nextcloud server, the JWT token will be rejected as being "not yet valid". This
can be seen in the logs (Nextcloud -> Settings -> Administration -> Logging).

The error message shown to the user when this happens is more generic:

"Error when trying to connect (Error occurred in the document service: Error
while downloading the document file to be converted.)"

This error message has been reported on the bug tracker several times, but it is
not clear when the connection failure was due to imperfectly synchronized clocks
and when it was due to network connectivity, DNS issues, the JWT not being sent,
the secret being wrong, or some other issue.

Here are the tickets that may be fixed by this:
#345
#548
#315
#290
#127

There's also one on the owncloud fork that may be fixed by this as well:
ONLYOFFICE/onlyoffice-owncloud#278
  • Loading branch information
anon8675309 authored and LinneyS committed Feb 25, 2023
1 parent 23381bf commit c76969a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 2 deletions.
2 changes: 2 additions & 0 deletions appinfo/application.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ public function register(IRegistrationContext $context): void {
if (!class_exists('\\Firebase\\JWT\\JWT')) {
require_once __DIR__ . "/../3rdparty/jwt/JWT.php";
}
// Set the leeway for the JWT library in case the system clock is a second off
\Firebase\JWT\JWT::$leeway = $this->appConfig->GetJwtLeeway();

$context->registerService("L10N", function (ContainerInterface $c) {
return $c->get("ServerContainer")->getL10N($c->get("AppName"));
Expand Down
8 changes: 6 additions & 2 deletions controller/settingscontroller.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ public function index() {
"tagsEnabled" => \OC::$server->getAppManager()->isEnabledForUser("systemtags"),
"reviewDisplay" => $this->config->GetCustomizationReviewDisplay(),
"theme" => $this->config->GetCustomizationTheme(),
"templates" => $this->GetGlobalTemplates()
"templates" => $this->GetGlobalTemplates(),
"jwtLeeway" => $this->config->GetJwtLeeway()
];
return new TemplateResponse($this->appName, "settings", $data, "blank");
}
Expand All @@ -154,7 +155,8 @@ public function SaveAddress($documentserver,
$storageUrl,
$verifyPeerOff,
$secret,
$demo
$demo,
$jwtLeeway
) {
$error = null;
if (!$this->config->SelectDemo($demo === true)) {
Expand All @@ -165,6 +167,7 @@ public function SaveAddress($documentserver,
$this->config->SetVerifyPeerOff($verifyPeerOff);
$this->config->SetDocumentServerInternalUrl($documentserverInternal);
$this->config->SetDocumentServerSecret($secret);
$this->config->SetJwtLeeway($jwtLeeway);
}
$this->config->SetStorageUrl($storageUrl);

Expand All @@ -184,6 +187,7 @@ public function SaveAddress($documentserver,
"documentserverInternal" => $this->config->GetDocumentServerInternalUrl(true),
"storageUrl" => $this->config->GetStorageUrl(),
"secret" => $this->config->GetDocumentServerSecret(true),
"jwtLeeway" => $this->config->GetJwtLeeway(),
"error" => $error,
"version" => $version,
];
Expand Down
3 changes: 3 additions & 0 deletions js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
var onlyofficeStorageUrl = ($("#onlyofficeStorageUrl:visible").val() || "").trim();
var onlyofficeVerifyPeerOff = $("#onlyofficeVerifyPeerOff").prop("checked");
var onlyofficeSecret = ($("#onlyofficeSecret:visible").val() || "").trim();
var onlyofficeJwtLeeway = ($("#onlyofficeJwtLeeway").val() || "0").trim();
var demo = $("#onlyofficeDemo").prop("checked");

$.ajax({
Expand All @@ -152,6 +153,7 @@
storageUrl: onlyofficeStorageUrl,
verifyPeerOff: onlyofficeVerifyPeerOff,
secret: onlyofficeSecret,
jwtLeeway: onlyofficeJwtLeeway,
demo: demo
},
success: function onSuccess(response) {
Expand All @@ -161,6 +163,7 @@
$("#onlyofficeInternalUrl").val(response.documentserverInternal);
$("#onlyofficeStorageUrl").val(response.storageUrl);
$("#onlyofficeSecret").val(response.secret);
$("#onlyofficeJwtLeeway").val(response.jwtLeeway);

$(".section-onlyoffice-common, .section-onlyoffice-templates, .section-onlyoffice-watermark").toggleClass("onlyoffice-hide", (!response.documentserver.length && !demo) || !!response.error.length);

Expand Down
28 changes: 28 additions & 0 deletions lib/appconfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ class AppConfig {
*/
private $_cryptSecret = "secret";

/**
* The config key for the allowable leeway in Jwt checks
*
* @var string
*/
private $_jwtLeeway = "JwtLeeway";

/**
* The config key for the default formats
*
Expand Down Expand Up @@ -585,6 +592,27 @@ public function GetDocumentServerSecret($origin = false) {
return $secret;
}

/**
* Save the Jwt Leeway to the application configuration
*
* @param string $jwtLeeway - number of seconds the docs/nextcloud clock can be off
*/
public function SetJwtLeeway($jwtLeeway) {
$this->logger->debug("Setting JwtLeeway to: " . json_encode($jwtLeeway), ["app" => $this->appName]);
$this->config->setAppValue($this->appName, $this->_jwtLeeway, $jwtLeeway);
}

/**
* Get the Jwt Leeway
*
* @return string
*/
public function GetJwtLeeway() {
$jwtLeeway = $this->config->getAppValue($this->appName, $this->_jwtLeeway, "0");
$this->logger->debug("JwtLeeqy: " . json_encode($jwtLeeway), ["app" => $this->appName]);
return $jwtLeeway;
}

/**
* Get the secret key from the application configuration
*
Expand Down
3 changes: 3 additions & 0 deletions templates/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@

<p class="onlyoffice-header"><?php p($l->t("Server address for internal requests from ONLYOFFICE Docs")) ?></p>
<p><input id="onlyofficeStorageUrl" value="<?php p($_["storageUrl"]) ?>" placeholder="<?php p($_["currentServer"]) ?>" type="text"></p>

<p class="onlyoffice-header"><?php p($l->t("Amount of leeway in system clocks between nextcloud and ONLYOFFICE Docs (in seconds)")) ?></p>
<p><input id="onlyofficeJwtLeeway" value="<?php p($_["jwtLeeway"]) ?>" placeholder="0" type="text"></p>
</div>
</div>

Expand Down

0 comments on commit c76969a

Please sign in to comment.