Skip to content

Commit

Permalink
Merge pull request #3762 from nextcloud/fix/code-autosetup-async
Browse files Browse the repository at this point in the history
Make built-in code server setup more stable
  • Loading branch information
juliushaertl committed Jun 20, 2024
2 parents f5b4b6a + 4158fbe commit 5b3dbf3
Show file tree
Hide file tree
Showing 22 changed files with 246 additions and 135 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module.exports = {
},
extends: [
'@nextcloud',
'@nextcloud/eslint-config/typescript',
'plugin:cypress/recommended',
],
env: {
Expand All @@ -28,5 +29,7 @@ module.exports = {
'jsdoc/require-param-description': 'off',
'jsdoc/require-param-type': 'off',
'jsdoc/require-property-description': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
}
}
57 changes: 2 additions & 55 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
Expand All @@ -7,7 +9,6 @@
namespace OCA\Richdocuments\AppInfo;

use OCA\Files_Sharing\Event\ShareLinkAccessedEvent;
use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Capabilities;
use OCA\Richdocuments\Db\WopiMapper;
use OCA\Richdocuments\Listener\AddContentSecurityPolicyListener;
Expand All @@ -28,11 +29,8 @@
use OCA\Richdocuments\Preview\OpenDocument;
use OCA\Richdocuments\Preview\Pdf;
use OCA\Richdocuments\Reference\OfficeTargetReferenceProvider;
use OCA\Richdocuments\Service\CapabilitiesService;
use OCA\Richdocuments\Service\DiscoveryService;
use OCA\Richdocuments\Template\CollaboraTemplateProvider;
use OCA\Viewer\Event\LoadViewer;
use OCP\App\IAppManager;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
Expand All @@ -45,7 +43,6 @@
use OCP\Preview\BeforePreviewFetchedEvent;
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
use OCP\Security\FeaturePolicy\AddFeaturePolicyEvent;
use OCP\Server;

class Application extends App implements IBootstrap {
public const APPNAME = 'richdocuments';
Expand All @@ -54,7 +51,6 @@ public function __construct(array $urlParams = []) {
parent::__construct(self::APPNAME, $urlParams);
}


public function register(IRegistrationContext $context): void {
$context->registerTemplateProvider(CollaboraTemplateProvider::class);
$context->registerCapability(Capabilities::class);
Expand Down Expand Up @@ -84,54 +80,5 @@ public function register(IRegistrationContext $context): void {
}

public function boot(IBootContext $context): void {
$this->checkAndEnableCODEServer();
}

public function checkAndEnableCODEServer() {
// Supported only on Linux OS, and x86_64 & ARM64 platforms
$supportedArchs = ['x86_64', 'aarch64'];
$osFamily = PHP_VERSION_ID >= 70200 ? PHP_OS_FAMILY : PHP_OS;
if ($osFamily !== 'Linux' || !in_array(php_uname('m'), $supportedArchs)) {
return;
}

$CODEAppID = (php_uname('m') === 'x86_64') ? 'richdocumentscode' : 'richdocumentscode_arm64';

if (Server::get(IAppManager::class)->isEnabledForUser($CODEAppID)) {
$appConfig = $this->getContainer()->get(AppConfig::class);
$wopi_url = $appConfig->getAppValue('wopi_url');
$isCODEEnabled = strpos($wopi_url, 'proxy.php?req=') !== false;

// Check if we have the wopi_url set to custom currently
if ($wopi_url !== null && $wopi_url !== '' && $isCODEEnabled === false) {
return;
}

$urlGenerator = \OC::$server->getURLGenerator();
$relativeUrl = $urlGenerator->linkTo($CODEAppID, '') . 'proxy.php';
$absoluteUrl = $urlGenerator->getAbsoluteURL($relativeUrl);
$new_wopi_url = $absoluteUrl . '?req=';

// Check if the wopi url needs to be updated
if ($isCODEEnabled && $wopi_url === $new_wopi_url) {
return;
}

$appConfig->setAppValue('wopi_url', $new_wopi_url);
$appConfig->setAppValue('disable_certificate_verification', 'yes');

/** @var DiscoveryService $discoveryService */
$discoveryService = $this->getContainer()->get(DiscoveryService::class);
/** @var CapabilitiesService $capabilitiesService */
$capabilitiesService = $this->getContainer()->get(CapabilitiesService::class);

$discoveryService->resetCache();
$capabilitiesService->resetCache();
try {
$capabilitiesService->fetch();
$discoveryService->fetch();
} catch (\Exception $e) {
}
}
}
}
64 changes: 62 additions & 2 deletions lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
namespace OCA\Richdocuments\Controller;

use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Capabilities;
use OCA\Richdocuments\Service\CapabilitiesService;
use OCA\Richdocuments\Service\ConnectivityService;
use OCA\Richdocuments\Service\DemoService;
use OCA\Richdocuments\Service\DiscoveryService;
use OCA\Richdocuments\Service\FontService;
use OCA\Richdocuments\UploadException;
use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\DataDisplayResponse;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\JSONResponse;
Expand All @@ -26,6 +26,7 @@
use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\PreConditionNotMetException;
use OCP\Util;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -431,4 +432,63 @@ private function getUploadedFile(string $key): array {
}
return $file;
}

#[Http\Attribute\FrontpageRoute(verb: 'GET', url: '/autosetup')]
public function setupCode(IURLGenerator $urlGenerator, IAppManager $appManager, Capabilities $capabilities): DataResponse {
$statusCode = Http::STATUS_NOT_MODIFIED;
// If no collabora url is configured and richdocumentscode is enabled we will configure it
// TODO If richdocumentscode is configured we attempt to fetch capabilities to start it

// Supported only on Linux OS, and x86_64 & ARM64 platforms
$supportedArchs = ['x86_64', 'aarch64'];
$architecture = php_uname('m');
if (PHP_OS_FAMILY !== 'Linux' || !in_array($architecture, $supportedArchs)) {
return new DataResponse([
'message' => 'Invalid architecture for built-in CODE server.'
], Http::STATUS_NOT_MODIFIED);
}

$CODEAppID = ($architecture === 'x86_64') ? 'richdocumentscode' : 'richdocumentscode_arm64';

if ($appManager->isEnabledForUser($CODEAppID)) {
$wopiUrl = $this->appConfig->getAppValue('wopi_url');
$isCODEEnabled = str_contains($wopiUrl, 'proxy.php?req=');

// Check if we have the wopi_url set to custom currently
if ($wopiUrl !== null && $wopiUrl !== '' && $isCODEEnabled === false) {
return new DataResponse([
'message' => 'An office server is already configured'
], Http::STATUS_NOT_MODIFIED);
}

$relativeUrl = $urlGenerator->linkTo($CODEAppID, '') . 'proxy.php';
$absoluteUrl = $urlGenerator->getAbsoluteURL($relativeUrl);
$new_wopi_url = $absoluteUrl . '?req=';

// Check if the wopi url needs to be updated
if ($isCODEEnabled && $wopiUrl === $new_wopi_url) {
return new DataResponse([
'message' => 'The built-in CODE server is already configured'
], Http::STATUS_NOT_MODIFIED);
}

$this->appConfig->setAppValue('wopi_url', $new_wopi_url);
$this->appConfig->setAppValue('disable_certificate_verification', 'yes');

$this->discoveryService->resetCache();
$this->capabilitiesService->resetCache();
try {
$this->capabilitiesService->fetch();
$this->discoveryService->fetch();
} catch (\Exception $e) {
return new DataResponse([
'message' => 'Failed to get proxy.php endpoints: ' . $e->getMessage(),
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}

return new DataResponse([
'capabilities' => $capabilities->getCapabilities()['richdocuments'],
], $statusCode);
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"build": "NODE_ENV=production webpack --progress --config webpack.js",
"dev": "NODE_ENV=development webpack --progress --config webpack.js",
"watch": "NODE_ENV=development webpack --progress --watch --config webpack.js",
"lint": "eslint --ext .js,.vue src",
"lint:fix": "eslint --ext .js,.vue src --fix",
"lint": "eslint --ext .js,.vue,.ts,.tsx src",
"lint:fix": "eslint --ext .js,.vue,.ts,.tsx src --fix",
"lint:cypress": "eslint --ext .js cypress",
"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css css/*.scss",
"stylelint:fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css css/*.scss --fix",
Expand Down
3 changes: 2 additions & 1 deletion src/components/AdminSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ import SettingsFontList from './SettingsFontList.vue'
import '@nextcloud/dialogs/style.css'
import { getCallbackBaseUrl } from '../helpers/url.js'
import { getCapabilities } from '../services/capabilities.ts'
const SERVER_STATE_OK = 0
const SERVER_STATE_LOADING = 1
Expand Down Expand Up @@ -529,7 +530,7 @@ export default {
const protocol = this.checkUrlProtocol(newVal)
const nextcloudProtocol = this.checkUrlProtocol(window.location.href)
if (protocol !== nextcloudProtocol) this.serverError = PROTOCOL_MISMATCH
else this.serverError = Object.values(OC.getCapabilities().richdocuments.collabora).length > 0 ? SERVER_STATE_OK : SERVER_STATE_CONNECTION_ERROR
else this.serverError = Object.values(getCapabilities().collabora).length > 0 ? SERVER_STATE_OK : SERVER_STATE_CONNECTION_ERROR
}
},
isSetup() {
Expand Down
8 changes: 3 additions & 5 deletions src/file-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { registerFileAction, FileAction } from '@nextcloud/files'
import { getCapabilities } from '@nextcloud/capabilities'
import { getCapabilities } from './services/capabilities.ts'
import { translate as t } from '@nextcloud/l10n'

// eslint-disable-next-line import/no-unresolved
import appIcon from '../img/app.svg?raw'

const richdocuments = getCapabilities().richdocuments

const openPdf = new FileAction({
id: 'office-open-pdf',

Expand All @@ -22,12 +20,12 @@ const openPdf = new FileAction({
displayName: () => {
return t('richdocuments',
'Edit with {productName}',
{ productName: richdocuments.productName })
{ productName: getCapabilities().productName })
},

enabled: () => {
// Only enable the file action when files_pdfviewer is enabled
const optionalMimetypes = richdocuments.mimetypesNoDefaultOpen
const optionalMimetypes = getCapabilities().mimetypesNoDefaultOpen
return optionalMimetypes.includes('application/pdf')
},

Expand Down
27 changes: 14 additions & 13 deletions src/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import FilesAppIntegration from './view/FilesAppIntegration.js'
import { splitPath } from './helpers/index.js'
import { enableScrollLock, disableScrollLock } from './helpers/safariFixer.js'
import NewFileMenu from './view/NewFileMenu.js'
import { getCapabilities } from './services/capabilities.ts'

const FRAME_DOCUMENT = 'FRAME_DOCUMENT'
const PostMessages = new PostMessageService({
Expand All @@ -34,11 +35,11 @@ const odfViewer = {
receivedLoading: false,
isProxyStarting: false,
isCollaboraConfigured: (
(OC.getCapabilities().richdocuments.config.wopi_url.indexOf('proxy.php') !== -1)
|| (typeof OC.getCapabilities().richdocuments.collabora === 'object' && OC.getCapabilities().richdocuments.collabora.length !== 0)),
supportedMimes: OC.getCapabilities().richdocuments.mimetypes.concat(OC.getCapabilities().richdocuments.mimetypesNoDefaultOpen),
excludeMimeFromDefaultOpen: OC.getCapabilities().richdocuments.mimetypesNoDefaultOpen,
hideDownloadMimes: OC.getCapabilities().richdocuments.mimetypesSecureView,
(getCapabilities().config.wopi_url.indexOf('proxy.php') !== -1)
|| (typeof getCapabilities().collabora === 'object' && getCapabilities().collabora.length !== 0)),
supportedMimes: getCapabilities().mimetypes.concat(getCapabilities().mimetypesNoDefaultOpen),
excludeMimeFromDefaultOpen: getCapabilities().mimetypesNoDefaultOpen,
hideDownloadMimes: getCapabilities().mimetypesSecureView,

onEdit(fileName, context) {
let fileDir
Expand All @@ -50,7 +51,7 @@ const odfViewer = {
if (!odfViewer.isCollaboraConfigured) {
$.get(generateOcsUrl('cloud/capabilities?format=json')).then(
e => {
if ((OC.getCapabilities().richdocuments.config.wopi_url.indexOf('proxy.php') !== -1)
if ((getCapabilities().config.wopi_url.indexOf('proxy.php') !== -1)
|| (typeof e.ocs.data.capabilities.richdocuments.collabora === 'object'
&& e.ocs.data.capabilities.richdocuments.collabora.length !== 0)) {
odfViewer.isCollaboraConfigured = true
Expand Down Expand Up @@ -101,11 +102,11 @@ const odfViewer = {

const $iframe = $('<iframe data-cy="documentframe" id="richdocumentsframe" nonce="' + btoa(OC.requestToken) + '" scrolling="no" allowfullscreen allow="clipboard-read *; clipboard-write *" src="' + documentUrl + '" />')
odfViewer.loadingTimeout = setTimeout(odfViewer.onTimeout,
(OC.getCapabilities().richdocuments.config.timeout * 1000 || 15000))
(getCapabilities().config.timeout * 1000 || 15000))
$iframe.src = documentUrl

if ((OC.appswebroots.richdocumentscode || OC.appswebroots.richdocumentscode_arm64)
&& OC.getCapabilities().richdocuments.config.wopi_url.indexOf('proxy.php') >= 0) {
&& getCapabilities().config.wopi_url.indexOf('proxy.php') >= 0) {
odfViewer.checkProxyStatus()
}

Expand Down Expand Up @@ -183,15 +184,15 @@ const odfViewer = {
...FilesAppIntegration.loggingContext(),
})
odfViewer.onClose()
OC.Notification.showTemporary(t('richdocuments', 'Failed to load {productName} - please try again later', { productName: OC.getCapabilities().richdocuments.productName || 'Collabora Online' }))
OC.Notification.showTemporary(t('richdocuments', 'Failed to load {productName} - please try again later', { productName: getCapabilities().productName || 'Collabora Online' }))
} else if (!odfViewer.receivedLoading) {
odfViewer.loadingTimeout = setTimeout(odfViewer.onTimeout,
(OC.getCapabilities().richdocuments.config.timeout * 1000 || 15000))
(getCapabilities().config.timeout * 1000 || 15000))
}
},

checkProxyStatus() {
const wopiUrl = OC.getCapabilities().richdocuments.config.wopi_url
const wopiUrl = getCapabilities().config.wopi_url
const url = wopiUrl.slice(0, wopiUrl.indexOf('proxy.php') + 'proxy.php'.length)
$.get(url + '?status').done(function(result) {
if (result && result.status) {
Expand All @@ -211,7 +212,7 @@ const odfViewer = {
},
}

const settings = OC.getCapabilities().richdocuments.config || {}
const settings = getCapabilities().config || {}
Config.update('ooxml', settings.doc_format === 'ooxml')

window.OCA.RichDocuments = {
Expand Down Expand Up @@ -297,7 +298,7 @@ addEventListener('DOMContentLoaded', () => {
})
odfViewer.onClose()
OC.Notification.showTemporary(t('richdocuments', 'Failed to connect to {productName}. Please try again later or contact your server administrator.',
{ productName: OC.getCapabilities().richdocuments.productName },
{ productName: getCapabilities().productName },
))
}
break
Expand Down
4 changes: 1 addition & 3 deletions src/helpers/getLoggedInUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
import { loadState } from '@nextcloud/initial-state'

/**
* Gets the current user's display name if logged in.
*
* @return boolean | string
* @return {boolean|string} Gets the current user's display name if logged in.
*/
function getLoggedInUser() {
return loadState('richdocuments', 'loggedInUser')
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/isDocument.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getCapabilities } from '@nextcloud/capabilities'
import { getCapabilities } from './../services/capabilities.ts'

/** @type Array.<String> */
const mimetypes = getCapabilities().richdocuments.mimetypes
const mimetypes = getCapabilities().mimetypes

/**
* Determines if the mimetype of the resource is supported by richdocuments
Expand Down
4 changes: 3 additions & 1 deletion src/helpers/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

const ooxml = OC.getCapabilities().richdocuments.config.doc_format === 'ooxml'
import { getCapabilities } from '../services/capabilities.ts'

const ooxml = getCapabilities().config.doc_format === 'ooxml'

const getFileTypes = () => {
if (ooxml) {
Expand Down
Loading

0 comments on commit 5b3dbf3

Please sign in to comment.